CFx SDK Documentation 2024 SP0
Loading...
Searching...
No Matches
FMSliceEngine.h
Go to the documentation of this file.
1
2// Copyright (C) 2002-2022, Open Design Alliance (the "Alliance").
3// All rights reserved.
4//
5// This software and its documentation and related materials are owned by
6// the Alliance. The software may only be incorporated into application
7// programs owned by members of the Alliance, subject to a signed
8// Membership Agreement and Supplemental Software License Agreement with the
9// Alliance. The structure and organization of this software are the valuable
10// trade secrets of the Alliance and its suppliers. The software is also
11// protected by copyright law and international treaty provisions. Application
12// programs incorporating this software must include the following statement
13// with their copyright notices:
14//
15// This application incorporates Open Design Alliance software pursuant to a license
16// agreement with Open Design Alliance.
17// Open Design Alliance Copyright (C) 2002-2022 by Open Design Alliance.
18// All rights reserved.
19//
20// By use of this software, its documentation or related materials, you
21// acknowledge and accept the above terms.
23#include "FMProfile3D.h"
24#include "FMGeometry.h"
25#include "FMGeometryDebug.h"
26#include "Modeler/FMMdlBody.h"
27#include "Modeler/FMMdlFace.h"
28#include "Modeler/FMMdlEdge.h"
34
35#include "Ge/GePlane.h"
36#include "Ge/GeLineSeg3d.h"
37#include <UInt32Array.h>
38#include "Si/SiSpatialIndex.h"
39#include "Si/SiShapePlane.h"
41#include "Si/SiShapeRay.h"
42#include "Ge/GeLine3d.h"
43#include "FMDebugDraw.h"
44//#include "../sampleapplications/TADebugTx/Debug.h"
45
46namespace FacetModeler
47{
48
49struct SpatialFaceData : public OdSiEntity {
54 const Face* face() const { return m_pFace; }
55
56 void detach() {
58 m_pFace = 0;
59 }
60
61 inline void attach( Face* pFace ) {
62 m_pFace = pFace;
63 m_savedTag = pFace->tag();
64 pFace->setTag( (TagType)this );
65 extents( pFace, m_ext3d );
66 extents( pFace, m_ext2d );
67 }
68
69 static void extents( const Face* pFace, OdGeExtents3d& extents ) {
70 Edge* pEdge = pFace->edge();
71 Edge* pEnd = pEdge;
72 const OdGePoint3d& pt = pEdge->vertex()->point();
73 extents.set( pt, pt );
74 do {
75 pEdge = pEdge->next();
76 extents.addPoint( pEdge->vertex()->point() );
77 }
78 while( pEdge != pEnd );
79 }
80
81 static void extents(const Face* pFace, OdGeExtents2d& extents) {
82
83 // FELIX_CHANGE_BEGIN
84 if ( pFace->plane().normal().isZeroLength() )
85 {
87 return;
88 }
89 // FELIX_CHANGE_END
90 OdGePlane plane(pFace->plane());
91
92 Edge* pEdge = pFace->edge();
93 Edge* pEnd = pEdge;
94 const OdGePoint2d& pt = plane.paramOf(pEdge->vertex()->point());
95 extents.set(pt, pt);
96 do {
97 pEdge = pEdge->next();
98 extents.addPoint(plane.paramOf(pEdge->vertex()->point()));
99 } while (pEdge != pEnd);
100 }
101
104 return true;
105 }
106
109 return true;
110 }
111
112 bool contains( const OdGeExtents3d& , bool , const OdGeTol& ) const {
113 return false;
114 }
115};
116
117
118template<class TSpatFData = SpatialFaceData>
120protected:
123private:
124 FaceSpatialIndex& operator = (const FaceSpatialIndex& ) { return *this; }
125public:
127 destroy( true );
128 }
129 OdSiSpatialIndex& build( const Body* pBody, double eps ) {
130 destroy();
131 OdUInt32 n = pBody->faceCount();
132 if ( n ) {
133 m_pFacesIndex = OdSiSpatialIndex::createObject( false, 0, 30, 20, eps );
134 m_spatialDataArray.resize( n );
135 TSpatFData* pSFD = m_spatialDataArray.asArrayPtr();
136 FaceIterator iter( pBody );
137 while( !iter.done() ) {
138 pSFD->attach( iter.get() );
139 m_pFacesIndex->insert( pSFD );
140 iter.next();
141 ++pSFD;
142 }
143 }
144 return *m_pFacesIndex.get();
145 }
146 void destroy( bool bRestoreFaceTags = true ) {
148 if( bRestoreFaceTags ) {
149 while( m_spatialDataArray.size() ) {
150 m_spatialDataArray.last().detach();
151 m_spatialDataArray.removeLast();
152 }
153 }
154 else {
155 m_spatialDataArray.clear();
156 }
157 }
158
161 return *m_pFacesIndex;
162 }
163
164 const OdSiSpatialIndex& index() const {
166 return *m_pFacesIndex;
167 }
168
170 OdUInt32 size() const {
172 return 0;
173 return m_spatialDataArray.size();
174 }
175};
176
178template<class T>
179inline static T mymax( T v1, T v2 ) {
180 return v1 > v2 ? v1 : v2;
181}
182
186
187
188
189//typedef OdArray<const Edge*, OdMemoryAllocator<const Edge*> > EdgeConstPtrArray;
190
197
199{
200 bool contains( const OdGeExtents3d& , bool , const OdGeTol& ) const
201 {
202 return false;
203 }
204
205 bool intersects( const OdGeExtents3d& extents, bool planar, const OdGeTol& tol ) const
206 {
207 return !extents.isDisjoint( m_ext3d, tol );
208 }
209
212};
214
215
216template<class TSpatialFaceData = SpatialFaceData>
217class Slicer : public SlicerBaseImpl,
218 protected OdSiVisitor
219{
220 void visit( OdSiEntity* pEntity, bool ) {
221 TSpatialFaceData* pFaceData = static_cast<TSpatialFaceData*>( pEntity );
222
223#ifdef _DEBUG
224 //IDebugAssist* pAssist = CreateDebugAssistant();
225 //pAssist->DebugDrawFace( pFaceData->face(), 0 );
226#endif
227
228 if (mode)
229 {
230 //collect_segments(pFaceData->face());
231 collect_face(pFaceData->face());
232 }
233 else
234 checkFaceByRay(pFaceData->face());
235 }
236public:
237 void initSlicerAndFaceIndex( const Body* pBody, FaceSpatialIndex<TSpatialFaceData>& faceSpatialIndex, double eps = OdGeTol().equalVector() ) {
238 reserveBuffers( pBody->faceCount() );
239 OdGeTol sitol = faceSpatialIndex.build( pBody, eps ).tolerance();
240 setTolerance( OdGeTol( sitol.equalPoint() / sitol.equalVector() * eps, eps ) );
241 }
242
243
244 void slice( const OdGePlane& cutPlane,
245 const FaceSpatialIndex<TSpatialFaceData>& faceSpatial,
246 Profile2D* pResultIncludingBoundary,
247 bool intOrDif = false,
248 Profile2D* pResultExcludingCoincidingBoundary = 0,
249 Profile2D* pResultExcludingOppositeBoundary = 0,
250 Profile2D* pResultExcludingBoundary = 0,
251 FaceConstPtrArray* pCoincidingFaces = 0,
252 FaceConstPtrArray* pOppositeFaces = 0,
253 bool bUseReverseEdgeAtMerge = false,
254 OdArray<const Edge*>* sourceEdges = 0,
255 const OdGeExtents3d* pCutPlaneBounds = 0,
256 const OdGeExtents2d* pCutFaceBox = 0)
257 {
259 setTolerance(OdGeTol(faceSpatial.index().tolerance().equalPoint(), 1e-5));
260 set_cut_plane( cutPlane );
261 ReserveBuffers( faceSpatial.size() );
263
264 /*
265 if (!pCutPlaneBounds || !pCutFaceBox)
266 faceSpatial.index().query( OdSiShapePlane( cutPlane ), *this );
267 else
268 {
269 faceSpatial.index().query(OdSiShapeBoundPlane(cutPlane, *pCutPlaneBounds), *this);
270 }
271 */
272
273 OdGeExtents2d incCutFaceBox;
274 OdGeExtents2d* pIncCutFaceBox = NULL;
275
276 if (!pCutPlaneBounds || !pCutFaceBox)
277 faceSpatial.index().query(OdSiShapePlane(cutPlane), *this);
278 else
279 {
280 // increasing the 2d and 3d boxes of face
281 // to process the cases when slice edge lies
282 // on 2d box side
283 ODA_ASSERT(pCutPlaneBounds && pCutFaceBox);
284 incCutFaceBox = *pCutFaceBox;
285 pIncCutFaceBox = &incCutFaceBox;
286
287 OdGePoint2d minPt = incCutFaceBox.minPoint();
288 OdGePoint2d maxPt = incCutFaceBox.maxPoint();
289
290 double origLenX = fabs(maxPt.x - minPt.x);
291 double origLenY = fabs(maxPt.y - minPt.y);
292
293 OdGeVector2d diag = incCutFaceBox.diagonal();
294 double diag_len = diag.length();
295 double step = 0.05;
296 int step_cnt = 0;
297 for (;;)
298 {
299 OdGePoint2d newMaxPt = maxPt + diag * step;
300 OdGePoint2d newMinPt = minPt - diag * step;
301
302 double newLenX = fabs(newMaxPt.x - newMinPt.x);
303 double newLenY = fabs(newMaxPt.y - newMinPt.y);
304
305 if ((fabs(newLenX - origLenX) > GetAddNodeTol() &&
306 fabs(newLenY - origLenY) > GetAddNodeTol()) ||
307 step_cnt == 9)
308 {
309 incCutFaceBox.set(newMinPt, newMaxPt);
310 break;
311 }
312
313 step += step;
314 step_cnt++;
315 }
316
317 OdGePoint2dArray box2dPts;
318 box2dPts.resize(4);
319 box2dPts[0] = incCutFaceBox.minPoint();
320 box2dPts[2] = incCutFaceBox.maxPoint();
321 box2dPts[1] = OdGePoint2d(box2dPts[2].x, box2dPts[0].y);
322 box2dPts[3] = OdGePoint2d(box2dPts[0].x, box2dPts[2].y);
323
324 OdGeExtents3d cutPlaneBounds = *pCutPlaneBounds;
325 for (int i = 0; i != 4; i++)
326 {
327 OdGePoint3d pt = cut_plane().evalPoint(box2dPts[i]);
328 cutPlaneBounds.addPoint(pt);
329 }
330 faceSpatial.index().query(OdSiShapeBoundPlane(cutPlane, cutPlaneBounds), *this);
331 }
332
334
335 bool checkFaceByRay = false;
336
337 build_results( pResultIncludingBoundary,
338 pResultExcludingCoincidingBoundary,
339 pResultExcludingOppositeBoundary,
340 pResultExcludingBoundary,
341 pCoincidingFaces, pOppositeFaces, bUseReverseEdgeAtMerge, checkFaceByRay, sourceEdges, pIncCutFaceBox, pCutFaceBox);
342
343 // checking face is inside or outside of body in case
344 // graph is empty
345 if (checkFaceByRay && pCutFaceBox)
346 {
347 mode = false;
348 OdGePoint3d rayStart = cut_plane().pointOnPlane();
349 OdGeVector3d rayDir = cut_plane().normal();
350 OdGeRay3d ray(rayStart, rayDir);
351 m_pRay = &ray;
352 faceSpatial.index().query(OdSiShapeRay(ray), *this);
353
354 bool inside = false;
355 if (m_rayFaceInters.size() % 2 == 1)
356 {
357 double dist = (rayStart - m_rayFaceInters.first().m_intPt).length();
358 if (dist > m_tol.equalPoint())
359 inside = true;
360 }
361
362 if (!inside && intOrDif)
363 {
364 if (!m_coinciding.isEmpty())
365 {
366 inside = true;
367 }
368 }
369
370 if (inside)
371 {
372 AddScaledBoxContour(*pCutFaceBox);
373 }
374
375 m_rayFaceInters.clear();
376 mode = true;
377
378 build_profiles(pResultIncludingBoundary,
379 pResultExcludingCoincidingBoundary,
380 pResultExcludingOppositeBoundary,
381 pResultExcludingBoundary,
382 pCoincidingFaces, pOppositeFaces, sourceEdges, pCutFaceBox);
383 }
384
385 // algo should not produce duplicates, but it does
386 if(pResultExcludingOppositeBoundary != NULL)
387 {
388 pResultExcludingOppositeBoundary->deleteCoincident(1.e-10);
389 }
390 }
391};
392
393}
#define ODA_ASSERT(exp)
Definition: DebugStuff.h:57
tol
Definition: DimVarDefs.h:2287
unsigned int OdUInt32
OdUInt32 faceCount() const
void ReserveBuffers(size_t nFaces)
double GetAddNodeTol(const OdGeTol tol=FMGeGbl::gTol) const
Edge * next() const
Vertex * vertex() const
TagType tag() const
Definition: FMMdlEntity.h:157
void setTag(TagType nTag)
Definition: FMMdlEntity.h:161
const OdGePlane & plane() const
Edge * edge(OdUInt32 nLoop=0) const
void destroy(bool bRestoreFaceTags=true)
const OdSiSpatialIndex & index() const
OdSiSpatialIndexPtr m_pFacesIndex
OdArray< TSpatFData > & faceDataArray()
OdSiSpatialIndex & build(const Body *pBody, double eps)
OdSiSpatialIndex & index()
OdArray< TSpatFData > m_spatialDataArray
OdArray< RayFaceIntersection > m_rayFaceInters
void reserveBuffers(size_t nFaces)
void setTolerance(const OdGeTol &tol)
void AddScaledBoxContour(const OdGeExtents2d &bbox)
const OdGePlane & cut_plane() const
void set_cut_plane(const OdGePlane &cutPlane)
void checkFaceByRay(const Face *pFace)
void build_profiles(Profile2D *pResInclBndry, Profile2D *pResExclCoBndry, Profile2D *pResExclOpBndry, Profile2D *pResExclBndry, FaceConstPtrArray *pCoincidingFaces, FaceConstPtrArray *pOppositeFaces, OdArray< const Edge * > *sourceEdges, const OdGeExtents2d *pBox)
void build_results(Profile2D *pResInclBndry, Profile2D *pResExclCoBndry, Profile2D *pResExclOpBndry, Profile2D *pResExclBndry, FaceConstPtrArray *pCoincidingFaces, FaceConstPtrArray *pOppositeFaces, bool bUseReverseEdgeAtMerge, bool &checkFaceByRay, OdArray< const Edge * > *sourceEdges=0, const OdGeExtents2d *pIncBox=0, const OdGeExtents2d *pOrigBox=0)
void collect_face(const Face *pFace)
void slice(const OdGePlane &cutPlane, const FaceSpatialIndex< TSpatialFaceData > &faceSpatial, Profile2D *pResultIncludingBoundary, bool intOrDif=false, Profile2D *pResultExcludingCoincidingBoundary=0, Profile2D *pResultExcludingOppositeBoundary=0, Profile2D *pResultExcludingBoundary=0, FaceConstPtrArray *pCoincidingFaces=0, FaceConstPtrArray *pOppositeFaces=0, bool bUseReverseEdgeAtMerge=false, OdArray< const Edge * > *sourceEdges=0, const OdGeExtents3d *pCutPlaneBounds=0, const OdGeExtents2d *pCutFaceBox=0)
void initSlicerAndFaceIndex(const Body *pBody, FaceSpatialIndex< TSpatialFaceData > &faceSpatialIndex, double eps=OdGeTol().equalVector())
const OdGePoint3d & point() const
bool isEmpty() const
Definition: OdArray.h:1547
void resize(size_type logicalLength, const T &value)
Definition: OdArray.h:1185
bool isNull() const
Definition: BaseObjectPtr.h:86
void set(const OdGePoint2d &min, const OdGePoint2d &max)
Definition: GeExtents2d.h:106
const OdGePoint2d & maxPoint() const
Definition: GeExtents2d.h:88
const OdGePoint2d & minPoint() const
Definition: GeExtents2d.h:79
static GE_STATIC_EXPORT const OdGeExtents2d kInvalid
Definition: GeExtents2d.h:71
OdGeVector2d diagonal() const
Definition: GeExtents2d.h:97
OdGeExtents3d & addPoint(const OdGePoint3d &point)
Definition: GeExtents3d.h:467
OdGePoint3d pointOnPlane() const
OdGeVector3d normal() const
double x
Definition: GePoint2d.h:409
double y
Definition: GePoint2d.h:410
OdGePoint2d paramOf(const OdGePoint3d &point, const OdGeTol &tol=OdGeContext::gTol) const
OdGePoint3d evalPoint(const OdGePoint2d &param) const
Definition: GeTol.h:49
double equalVector() const
Definition: GeTol.h:84
double equalPoint() const
Definition: GeTol.h:76
double length() const
bool isZeroLength(const OdGeTol &tol=OdGeContext::gTol) const
static OdSiSpatialIndexPtr createObject(OdUInt32 flags, unsigned int initialNumEntity, unsigned int maxDepth=30, unsigned int maxCount=20, double eps=1e-10)
virtual void insert(OdSiEntity *entity)=0
virtual void query(const OdSiShape &shape, OdSiVisitor &visitor) const =0
virtual const OdGeTol & tolerance() const =0
void release()
Definition: SmartPtr.h:269
const T * get() const
Definition: SmartPtr.h:339
GLfloat GLfloat v1
Definition: gles2_ext.h:295
GLfloat GLfloat GLfloat v2
Definition: gles2_ext.h:296
GLuint GLsizei GLsizei * length
Definition: gles2_ext.h:274
GLfloat x
Definition: gles2_ext.h:314
GLfloat GLfloat y
Definition: gles2_ext.h:316
OdArray< Face *, OdMemoryAllocator< Face * > > FacePtrArray
OdArray< const Face *, OdMemoryAllocator< const Face * > > FaceConstPtrArray
Definition: FMMdlFace.h:412
OdArray< Vertex *, OdMemoryAllocator< Vertex * > > VertexIndex
ptrdiff_t TagType
Definition: FMMdlBase.h:46
bool contains(const OdGeExtents3d &, bool, const OdGeTol &) const
bool intersects(const OdGeExtents3d &extents, bool planar, const OdGeTol &tol) const
bool extents(OdGeExtents3d &extents) const
static void extents(const Face *pFace, OdGeExtents2d &extents)
Definition: FMSliceEngine.h:81
bool contains(const OdGeExtents3d &, bool, const OdGeTol &) const
const Face * face() const
Definition: FMSliceEngine.h:54
bool extents(OdGeExtents2d &extents) const
static void extents(const Face *pFace, OdGeExtents3d &extents)
Definition: FMSliceEngine.h:69