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
33 using Sphere = Sphere3<float>;
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;
98 [[nodiscard]] MRMESH_API ConeSegment extendToInfinity() 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{
170 enum class Status
171 {
172 ok = 0,
181 notFinite,
182 };
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 };
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
234 MRMESH_API void swapObjects();
235};
237[[nodiscard]] MRMESH_API std::string_view toString( MeasureResult::Status status );
238
240namespace Traits
241{
242
243template <typename T>
244struct Unary {};
245template <>
246struct Unary<Primitives::Sphere>
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 <>
256struct Unary<Primitives::Plane>
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 <>
274struct Binary<Primitives::Sphere, Primitives::Sphere>
275{
276 MRMESH_API MeasureResult measure( const Primitives::Sphere& a, const Primitives::Sphere& b ) const;
277};
278template <>
279struct Binary<Primitives::ConeSegment, Primitives::Sphere>
280{
281 MRMESH_API MeasureResult measure( const Primitives::ConeSegment& a, const Primitives::Sphere& b ) const;
282};
283template <>
284struct Binary<Primitives::Plane, Primitives::Sphere>
285{
286 MRMESH_API MeasureResult measure( const Primitives::Plane& a, const Primitives::Sphere& b ) const;
287};
288
290template <>
291struct Binary<Primitives::ConeSegment, Primitives::ConeSegment>
292{
294};
295template <>
297{
298 MRMESH_API MeasureResult measure( const Primitives::Plane& a, const Primitives::ConeSegment& b ) const;
299};
300
302template <>
303struct Binary<Primitives::Plane, Primitives::Plane>
304{
305 MRMESH_API MeasureResult measure( const Primitives::Plane& a, const Primitives::Plane& b ) const;
306};
307
308}
309
311template <typename T>
312[[nodiscard]] std::string name( const T& primitive )
313{
314 return Traits::Unary<T>{}.name( primitive );
315}
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}
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}
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}
381[[nodiscard]] MRMESH_API MeasureResult measure( const Primitives::Variant& a, const Primitives::Variant& b );
382
383}
named object in the data model
Definition MRObject.h:62
Whether you can measure two primitives relative to one another.
Definition MRFeatures.h:321
MRMESH_API void swapObjects()
Modifies the object to swap A and B;.
friend bool operator==(const ConeSegment &, const ConeSegment &)=default
Vector3f pointA
Definition MRFeatures.h:212
Vector3f center
Definition MRFeatures.h:37
MRMESH_API MeasureResult measure(const Primitives::Plane &a, const Primitives::ConeSegment &b) const
Vector3f dirFor(bool b) const
^
Definition MRFeatures.h:218
std::string name(const T &primitive)
Get name of a Primitives::... class (can depend on its parameters).
Definition MRFeatures.h:312
MRMESH_API MeasureResult measure(const Primitives::Plane &a, const Primitives::Sphere &b) const
MRMESH_API MeasureResult measure(const Primitives::Plane &a, const Primitives::Plane &b) const
float length() const
Returns the length. Can be infinite.
Definition MRFeatures.h:88
MRMESH_API Primitives::ConeSegment primitiveCylinder(const Vector3f &a, const Vector3f &b, float rad)
a and b are centers of the sides.
MRMESH_API Sphere basePoint(bool negative) const
Returns a center of one of the two base circles.
Distance centerDistance
Definition MRFeatures.h:208
float distanceAlongAxis(int i) const
Definition MRFeatures.h:200
Sphere3< float > Sphere
Doubles as a point when the radius is zero.
Definition MRFeatures.h:33
MRMESH_API MeasureResult measure(const Primitives::ConeSegment &a, const Primitives::Sphere &b) const
MeasureResult measure(const A &a, const B &b)
Measures stuff between two primitives. (Two types from Primitives::....)
Definition MRFeatures.h:326
MRMESH_API ConeSegment extendToInfinity() const
MRMESH_API float computeAngleInRadians() const
Vector3f referencePoint
Some point on the axis, but not necessarily the true center point. Use centerPoint() for that.
Definition MRFeatures.h:65
MRMESH_API ConeSegment baseCircle(bool negative) const
Returns one of the two base circles.
MRMESH_API std::shared_ptr< FeatureObject > primitiveToObject(const Primitives::Variant &primitive, float infiniteExtent)
MRMESH_API Sphere intersectWithLine(const ConeSegment &line) const
MRMESH_API ConeSegment untruncateCone() const
Untruncates a truncated cone. If it's not a cone at all, returns the object unchanged and triggers an...
MRMESH_API Primitives::ConeSegment primitiveCircle(const Vector3f &point, const Vector3f &normal, float rad)
normal doesn't need to be normalized.
Angle angle
Definition MRFeatures.h:228
MRMESH_API std::string name(const Primitives::ConeSegment &prim) const
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
MRMESH_API std::string_view toString(MeasureResult::Status status)
MeasureResult::Status enum to string.
Vector3f dirA
Definition MRFeatures.h:216
MRMESH_API Primitives::Sphere transformPrimitive(const AffineXf3f &xf, const Primitives::Sphere &primitive)
MRMESH_API std::string name(const Primitives::Sphere &prim) const
MRMESH_API ConeSegment intersectWithPlane(const Plane &other) const
Returns an infinite line, with the center in a sane location.
Status status
Definition MRFeatures.h:186
Vector3f closestPointFor(bool b) const
Definition MRFeatures.h:198
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
MRMESH_API Primitives::ConeSegment primitiveCone(const Vector3f &a, const Vector3f &b, float rad)
a is the center of the base, b is the pointy end.
Vector3f pointFor(bool b) const
Definition MRFeatures.h:214
std::variant< Sphere, ConeSegment, Plane > Variant
Definition MRFeatures.h:114
MRMESH_API MeasureResult measure(const Primitives::Sphere &a, const Primitives::Sphere &b) const
Vector3f dir
The axis direction. Must be normalized.
Definition MRFeatures.h:67
MRMESH_API Sphere centerPoint() const
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
Vector3f closestPointB
Definition MRFeatures.h:196
MRMESH_API Plane basePlane(bool negative) const
Returns one of the two base planes.
Vector3f normal
This must be normalized. The sign doesn't matter.
Definition MRFeatures.h:40
MRMESH_API std::optional< Primitives::Variant > primitiveFromObjectWithWorldXf(const Object &object)
Returns null if the object type is unknown. This overload respects the parent's worldXf().
Status
Definition MRFeatures.h:171
float distance
This is a separate field because it can be negative.
Definition MRFeatures.h:193
float negativeSideRadius
Cap radius in the direction opposite to dir.
Definition MRFeatures.h:72
MRMESH_API ConeSegment axis() const
Returns a finite axis. For circles, you might want to immediately extendToInfinity() it.
float positiveLength
Distance from the center to the cap in the dir direction.
Definition MRFeatures.h:75
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
bool isZeroRadius() const
Definition MRFeatures.h:84
MRMESH_API std::string name(const Primitives::Plane &prim) const
MRMESH_API MeasureResult measure(const Primitives::ConeSegment &a, const Primitives::ConeSegment &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
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
MRMESH_API ConeSegment extendToInfinity(bool negative) const
Extends the object to infinity in one direction. The radius in the extended direction becomes equal t...
MRMESH_API std::optional< Primitives::Variant > primitiveFromObject(const Object &object)
Returns null if the object type is unknown. This overload ignores the parent xf.
length
Definition MRObjectDimensionsEnum.h:17
bool isCircle() const
Definition MRFeatures.h:85
@ other
Angle, normally float. Measure in radians.
@ badRelativeLocation
Can't be computed because of how the objects are located relative to each other.
@ notImplemented
Algorithms set this if this when something isn't yet implemented.
@ notFinite
The result was not finite. This is set automatically if you return non-finite values,...
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