MeshLib C++ Docs
Loading...
Searching...
No Matches
MRFeatures.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRMesh/MRAffineXf.h"
4#include "MRMesh/MRCone3.h"
6#include "MRMesh/MRPlane3.h"
7#include "MRMesh/MRSphere.h"
8#include "MRMesh/MRVector3.h"
9
10#include <cassert>
11#include <optional>
12#include <variant>
13
14namespace MR
15{
18
19class FeatureObject;
20}
21
22namespace MR::Features
23{
24
25namespace Primitives
26{
27 struct Plane;
28 struct ConeSegment;
29
31
34
35 struct Plane
36 {
37 Vector3f center;
38
40 Vector3f normal = Vector3f( 1, 0, 0 );
41
43 [[nodiscard]] MRMESH_API ConeSegment intersectWithPlane( const Plane& other ) const;
44
48 [[nodiscard]] MRMESH_API Sphere intersectWithLine( const ConeSegment& line ) const;
49
50 friend bool operator==( const Plane&, const Plane& ) = default;
51 };
52
57 {
63
67 Vector3f dir;
68
73
75 float positiveLength = 0;
77 float negativeLength = 0;
78
80 bool hollow = false;
81
82 friend bool operator==( const ConeSegment&, const ConeSegment& ) = default;
83
84 [[nodiscard]] bool isZeroRadius() const { return positiveSideRadius == 0 && negativeSideRadius == 0; }
85 [[nodiscard]] bool isCircle() const { return positiveLength == -negativeLength && std::isfinite( positiveLength ); }
86
88 [[nodiscard]] float length() const { return positiveLength + negativeLength; }
89
92 [[nodiscard]] MRMESH_API Sphere centerPoint() const;
93
95 [[nodiscard]] MRMESH_API ConeSegment extendToInfinity( bool negative ) const;
99
101 [[nodiscard]] MRMESH_API ConeSegment untruncateCone() const;
102
104 [[nodiscard]] MRMESH_API ConeSegment axis() const;
105
107 [[nodiscard]] MRMESH_API Sphere basePoint( bool negative ) const;
109 [[nodiscard]] MRMESH_API Plane basePlane( bool negative ) const;
111 [[nodiscard]] MRMESH_API ConeSegment baseCircle( bool negative ) const;
112 };
113
114 using Variant = std::variant<Sphere, ConeSegment, Plane>;
115}
116
118
119[[nodiscard]] inline Primitives::Sphere toPrimitive( const Vector3f& point ) { return { point, 0 }; }
120[[nodiscard]] inline Primitives::Sphere toPrimitive( const Sphere3f& sphere ) { return sphere; }
121
122[[nodiscard]] MRMESH_API Primitives::ConeSegment toPrimitive( const Line3f& line );
123[[nodiscard]] MRMESH_API Primitives::ConeSegment toPrimitive( const LineSegm3f& segm );
124
125[[nodiscard]] inline Primitives::ConeSegment toPrimitive( const Cylinder3f& cyl )
126{
127 float halfLen = cyl.length / 2;
128 return{
129 .referencePoint = cyl.center(),
130 .dir = cyl.direction().normalized(),
131 .positiveSideRadius = cyl.radius, .negativeSideRadius = cyl.radius,
132 .positiveLength = halfLen, .negativeLength = halfLen,
133 };
134}
135[[nodiscard]] inline Primitives::ConeSegment toPrimitive( const Cone3f& cone )
136{
137 return{
138 .referencePoint = cone.center(),
139 .dir = cone.direction().normalized(),
140 .positiveSideRadius = std::tan( cone.angle ) * cone.height, .negativeSideRadius = 0,
141 .positiveLength = cone.height, .negativeLength = 0,
142 };
143}
144
146[[nodiscard]] MRMESH_API Primitives::ConeSegment primitiveCircle( const Vector3f& point, const Vector3f& normal, float rad );
148[[nodiscard]] MRMESH_API Primitives::ConeSegment primitiveCylinder( const Vector3f& a, const Vector3f& b, float rad );
150[[nodiscard]] MRMESH_API Primitives::ConeSegment primitiveCone( const Vector3f& a, const Vector3f& b, float rad );
151
153[[nodiscard]] MRMESH_API std::optional<Primitives::Variant> primitiveFromObject( const Object& object );
155[[nodiscard]] MRMESH_API std::optional<Primitives::Variant> primitiveFromObjectWithWorldXf( const Object& object );
158[[nodiscard]] MRMESH_API std::shared_ptr<FeatureObject> primitiveToObject( const Primitives::Variant& primitive, float infiniteExtent );
159
162[[nodiscard]] MRMESH_API Primitives::Sphere transformPrimitive( const AffineXf3f& xf, const Primitives::Sphere& primitive );
163[[nodiscard]] MRMESH_API Primitives::Plane transformPrimitive( const AffineXf3f& xf, const Primitives::Plane& primitive );
164[[nodiscard]] MRMESH_API Primitives::ConeSegment transformPrimitive( const AffineXf3f& xf, const Primitives::ConeSegment& primitive );
165[[nodiscard]] MRMESH_API Primitives::Variant transformPrimitive( const AffineXf3f& xf, const Primitives::Variant& primitive );
166
169{
183
185 {
187 [[nodiscard]] operator bool() const { return status == Status::ok; }
188 };
189
191 {
193 float distance = 0;
194
197
198 [[nodiscard]] Vector3f closestPointFor( bool b ) const { return b ? closestPointB : closestPointA; }
199
200 [[nodiscard]] float distanceAlongAxis( int i ) const { return distanceAlongAxisAbs( i ) * ( distance < 0 ? -1 : 1 ); }
201 [[nodiscard]] float distanceAlongAxisAbs( int i ) const { return std::abs( closestPointA[i] - closestPointB[i] ); }
202 };
203
205
209
211 {
212 Vector3f pointA;
213 Vector3f pointB;
214 [[nodiscard]] Vector3f pointFor( bool b ) const { return b ? pointB : pointA; }
215
216 Vector3f dirA;
217 Vector3f dirB;
218 [[nodiscard]] Vector3f dirFor( bool b ) const { return b ? dirB : dirA; }
219
221 bool isSurfaceNormalA = false;
222 bool isSurfaceNormalB = false;
223
224 [[nodiscard]] bool isSurfaceNormalFor( bool b ) const { return b ? isSurfaceNormalB : isSurfaceNormalA; }
225
226 [[nodiscard]] MRMESH_API float computeAngleInRadians() const;
227 };
229
231 std::vector<Primitives::Variant> intersections;
232
235};
236
237[[nodiscard]] MRMESH_API std::string_view toString( MeasureResult::Status status );
238
240namespace Traits
241{
242
243template <typename T>
244struct Unary {};
245template <>
247{
248 MRMESH_API std::string name( const Primitives::Sphere& prim ) const;
249};
250template <>
251struct Unary<Primitives::ConeSegment>
252{
253 MRMESH_API std::string name( const Primitives::ConeSegment& prim ) const;
254};
255template <>
257{
258 MRMESH_API std::string name( const Primitives::Plane& prim ) const;
259};
260
261template <typename A, typename B>
262struct Binary {};
263
266template <typename A, typename B>
267concept MeasureSupportedOneWay = requires( const Binary<A, B>& t, const A& a, const B& b )
268{
269 { t.measure( a, b ) } -> std::same_as<MeasureResult>;
270};
271
273template <>
278template <>
283template <>
288
290template <>
295template <>
300
302template <>
307
308}
309
311template <typename T>
312[[nodiscard]] std::string name( const T& primitive )
313{
314 return Traits::Unary<T>{}.name( primitive );
315}
316
317[[nodiscard]] MRMESH_API std::string name( const Primitives::Variant& var );
318
320template <typename A, typename B>
322
324template <typename A, typename B>
326[[nodiscard]] MeasureResult measure( const A& a, const B& b )
327{
329 {
330 MeasureResult ret = Traits::Binary<A, B>{}.measure( a, b );
331
332 for ( auto* dist : { &ret.distance, &ret.centerDistance } )
333 {
335 if ( *dist && ( !std::isfinite( dist->distance ) || !dist->closestPointA.isFinite() || !dist->closestPointB.isFinite() ) )
337
340 if ( *dist )
341 {
342 assert( [&]{
343 float a = ( dist->closestPointB - dist->closestPointA ).length();
344 float b = std::abs( dist->distance );
345 return std::abs( a - b ) <= std::max( std::min( a, b ), 0.01f ) * 0.001f;
346 }() );
347 }
348 }
349
351 if ( ret.angle && ( !ret.angle.pointA.isFinite() || !ret.angle.pointB.isFinite() || !ret.angle.dirA.isFinite() || !ret.angle.dirB.isFinite() ) )
353
355 assert( ret.angle <= ( std::abs( 1 - ret.angle.dirA.length() ) < 0.0001f ) );
356 assert( ret.angle <= ( std::abs( 1 - ret.angle.dirB.length() ) < 0.0001f ) );
357
358 return ret;
359 }
360 else
361 {
362 static_assert( Traits::MeasureSupportedOneWay<B, A>, "This should never fail." );
363 MeasureResult ret = ( measure )( b, a );
364 ret.swapObjects();
365 return ret;
366 }
367}
368
369template <typename B>
370[[nodiscard]] MeasureResult measure( const Primitives::Variant& a, const B& b )
371{
372 return std::visit( [&]( const auto& elem ){ return (measure)( elem, b ); }, a );
373}
374
375template <typename A>
376[[nodiscard]] MeasureResult measure( const A& a, const Primitives::Variant& b )
377{
378 return std::visit( [&]( const auto& elem ){ return (measure)( a, elem ); }, b );
379}
380
382
383}
#define MRMESH_API
Definition MRMeshFwd.h:80
An interface class which allows feature objects to share setters and getters on their main properties...
Definition MRFeatureObject.h:96
named object in the data model
Definition MRObject.h:62
Whether you can measure two primitives relative to one another.
Definition MRFeatures.h:321
std::string name(const Primitives::ConeSegment &prim) const
friend bool operator==(const ConeSegment &, const ConeSegment &)=default
std::optional< Primitives::Variant > primitiveFromObjectWithWorldXf(const Object &object)
Returns null if the object type is unknown. This overload respects the parent's worldXf().
Vector3f pointA
Definition MRFeatures.h:212
Primitives::ConeSegment primitiveCone(const Vector3f &a, const Vector3f &b, float rad)
a is the center of the base, b is the pointy end.
MeasureResult measure(const Primitives::ConeSegment &a, const Primitives::ConeSegment &b) const
Vector3f center
Definition MRFeatures.h:37
Vector3f dirFor(bool b) const
^
Definition MRFeatures.h:218
ConeSegment intersectWithPlane(const Plane &other) const
Returns an infinite line, with the center in a sane location.
Cylinder3f
Definition MRMeshFwd.h:366
std::string name(const T &primitive)
Get name of a Primitives::... class (can depend on its parameters).
Definition MRFeatures.h:312
float length() const
Returns the length. Can be infinite.
Definition MRFeatures.h:88
Distance centerDistance
Definition MRFeatures.h:208
float distanceAlongAxis(int i) const
Definition MRFeatures.h:200
std::string_view toString(MeasureResult::Status status)
MeasureResult::Status enum to string.
Sphere3< float > Sphere
Doubles as a point when the radius is zero.
Definition MRFeatures.h:33
MeasureResult measure(const A &a, const B &b)
Measures stuff between two primitives. (Two types from Primitives::....)
Definition MRFeatures.h:326
MeasureResult measure(const Primitives::Plane &a, const Primitives::Plane &b) const
Primitives::ConeSegment primitiveCylinder(const Vector3f &a, const Vector3f &b, float rad)
a and b are centers of the sides.
Vector3f referencePoint
Some point on the axis, but not necessarily the true center point. Use centerPoint() for that.
Definition MRFeatures.h:65
ConeSegment baseCircle(bool negative) const
Returns one of the two base circles.
Angle angle
Definition MRFeatures.h:228
void swapObjects()
Modifies the object to swap A and B;.
Distance distance
Exact distance.
Definition MRFeatures.h:204
Vector3f pointB
Definition MRFeatures.h:213
Vector3f closestPointA
Definition MRFeatures.h:195
float positiveSideRadius
Cap radius in the dir direction.
Definition MRFeatures.h:70
Vector3f dirA
Definition MRFeatures.h:216
Sphere< Vector3< T > > Sphere3
Definition MRMeshFwd.h:335
std::optional< Primitives::Variant > primitiveFromObject(const Object &object)
Returns null if the object type is unknown. This overload ignores the parent xf.
Status status
Definition MRFeatures.h:186
Vector3f closestPointFor(bool b) const
Definition MRFeatures.h:198
MeasureResult measure(const Primitives::ConeSegment &a, const Primitives::Sphere &b) const
ConeSegment axis() const
Returns a finite axis. For circles, you might want to immediately extendToInfinity() it.
friend bool operator==(const Plane &, const Plane &)=default
bool isSurfaceNormalA
Whether dir{A,B} is a surface normal or a line direction.
Definition MRFeatures.h:221
Vector3f pointFor(bool b) const
Definition MRFeatures.h:214
Primitives::ConeSegment primitiveCircle(const Vector3f &point, const Vector3f &normal, float rad)
normal doesn't need to be normalized.
std::variant< Sphere, ConeSegment, Plane > Variant
Definition MRFeatures.h:114
Sphere intersectWithLine(const ConeSegment &line) const
std::shared_ptr< FeatureObject > primitiveToObject(const Primitives::Variant &primitive, float infiniteExtent)
Plane basePlane(bool negative) const
Returns one of the two base planes.
ConeSegment extendToInfinity(bool negative) const
Extends the object to infinity in one direction. The radius in the extended direction becomes equal t...
Vector3f dir
The axis direction. Must be normalized.
Definition MRFeatures.h:67
float negativeLength
Distance from the center to the cap in the direction opposite to dir.
Definition MRFeatures.h:77
float distanceAlongAxisAbs(int i) const
Definition MRFeatures.h:201
ConeSegment untruncateCone() const
Untruncates a truncated cone. If it's not a cone at all, returns the object unchanged and triggers an...
Primitives::Sphere transformPrimitive(const AffineXf3f &xf, const Primitives::Sphere &primitive)
Vector3f closestPointB
Definition MRFeatures.h:196
Cone3f
Definition MRMeshFwd.h:371
Vector3f normal
This must be normalized. The sign doesn't matter.
Definition MRFeatures.h:40
Status
Definition MRFeatures.h:171
float distance
This is a separate field because it can be negative.
Definition MRFeatures.h:193
Sphere basePoint(bool negative) const
Returns a center of one of the two base circles.
float negativeSideRadius
Cap radius in the direction opposite to dir.
Definition MRFeatures.h:72
float positiveLength
Distance from the center to the cap in the dir direction.
Definition MRFeatures.h:75
std::string name(const Primitives::Sphere &prim) const
bool isSurfaceNormalFor(bool b) const
Definition MRFeatures.h:224
Primitives::Sphere toPrimitive(const Vector3f &point)
Those map various MR types to our primitives. Some of those are identity functions.
Definition MRFeatures.h:119
MeasureResult measure(const Primitives::Plane &a, const Primitives::Sphere &b) const
bool isZeroRadius() const
Definition MRFeatures.h:84
std::string name(const Primitives::Plane &prim) const
MeasureResult measure(const Primitives::Sphere &a, const Primitives::Sphere &b) const
Vector3f dirB
Normalized.
Definition MRFeatures.h:217
std::vector< Primitives::Variant > intersections
The primitives obtained from intersecting those two.
Definition MRFeatures.h:231
Vector3f normal(const MeshTopology &topology, const VertCoords &points, FaceId f)
computes triangular face normal from its vertices
Definition MRMeshMath.h:224
bool hollow
If true, the cone has no caps and no volume, and all distances (to the conical surface,...
Definition MRFeatures.h:80
bool isSurfaceNormalB
Definition MRFeatures.h:222
length
Definition MRObjectDimensionsEnum.h:17
MeasureResult measure(const Primitives::Plane &a, const Primitives::ConeSegment &b) const
bool isCircle() const
Definition MRFeatures.h:85
@ Plane
Definition MRFeatureHelpers.h:25
@ other
Angle, normally float. Measure in radians.
Definition MRFeatureObject.h:27
@ badFeaturePair
Definition MRFeatures.h:177
@ ok
Definition MRFeatures.h:172
@ badRelativeLocation
Can't be computed because of how the objects are located relative to each other.
Definition MRFeatures.h:179
@ notImplemented
Algorithms set this if this when something isn't yet implemented.
Definition MRFeatures.h:174
@ notFinite
The result was not finite. This is set automatically if you return non-finite values,...
Definition MRFeatures.h:181
Definition MRFeatures.h:26
Traits that determine how the primitives are related.
Definition MRFeatures.h:241
Definition MRFeatures.h:23
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
Definition MRFeatures.h:211
Definition MRFeatures.h:185
Definition MRFeatures.h:191
Stores the results of measuring two objects relative to one another.
Definition MRFeatures.h:169
Definition MRFeatures.h:57
Definition MRFeatures.h:36
Definition MRFeatures.h:262
Definition MRFeatures.h:244
Definition MRSphere.h:14