CFx SDK Documentation 2024 SP0
Loading...
Searching...
No Matches
FMMdlSlicerBaseImpl.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
24#ifndef AECSLICERBASEIMPL_H_INCLUDED
25#define AECSLICERBASEIMPL_H_INCLUDED
26
27#include "FMProfile3D.h"
28#include "FMGeometry.h"
29#include "FMGeometryDebug.h"
30#include "Modeler/FMMdlBody.h"
31#include "Modeler/FMMdlFace.h"
32#include "Modeler/FMMdlEdge.h"
37
38#include "Ge/GePlane.h"
39#include "Ge/GeLineSeg3d.h"
40#include <UInt32Array.h>
41#include "Si/SiSpatialIndex.h"
42#include "Si/SiShapePlane.h"
43#include "Ge/GeLine3d.h"
44#include "FMDebugDraw.h"
45//#include "../sampleapplications/TADebugTx/Debug.h"
46
47template<typename _Tv>
49{
50 template<typename _Td>
51 struct _Node
52 {
53 _Node* pNext;
54 _Node* pPrev;
55 _Td data;
56
57 _Node()
58 {
59 pNext = NULL;
60 pPrev = NULL;
61 }
62 };
63
64 typedef _Node<_Tv> Node;
65
66 Node* m_pFirstNode;
67 int m_iNodeCount;
68
69public:
71 {
72 friend class cycled_list<_Tv>;
73
74 Node* m_pCurrentNode;
75
76 iterator(Node* pNode)
77 {
78 m_pCurrentNode = pNode;
79 }
80
81 public:
82 iterator(const iterator& it)
83 {
84 m_pCurrentNode = it.m_pCurrentNode;
85 }
86
88 {
89 m_pCurrentNode = m_pCurrentNode->pNext;
90 }
91
93 {
94 m_pCurrentNode = m_pCurrentNode->pPrev;
95 }
96
97 bool operator == (const iterator& it) const
98 {
99 return m_pCurrentNode == it.m_pCurrentNode;
100 }
101
102 bool operator != (const iterator& it) const
103 {
104 return m_pCurrentNode != it.m_pCurrentNode;
105 }
106
107 const _Tv& data() const
108 {
109 return m_pCurrentNode->data;
110 }
111
112 _Tv& data()
113 {
114 return m_pCurrentNode->data;
115 }
116
117 const _Tv& next_node_data()
118 {
119 return m_pCurrentNode->pNext->data;
120 }
121
122 const _Tv& prev_node_data()
123 {
124 return m_pCurrentNode->pPrev->data;
125 }
126
127 _Tv get()
128 {
129 return m_pCurrentNode->data;
130 }
131
133 {
134 return iterator(m_pCurrentNode->pNext);
135 }
136 };
137
138public:
140 {
141 m_iNodeCount = 0;
142 m_pFirstNode = NULL;
143 }
144
146 {
147 clear();
148 }
149
150 bool empty() const
151 {
152 return m_iNodeCount == 0;
153 }
154
155 void clear()
156 {
157 m_iNodeCount = 0;
158 if(m_pFirstNode == NULL)
159 return;
160
161 Node* pDeleteNode = m_pFirstNode->pNext;
162 while(pDeleteNode != m_pFirstNode)
163 {
164 pDeleteNode = pDeleteNode->pNext;
165 delete pDeleteNode->pPrev;
166 }
167
168 delete m_pFirstNode;
169 m_pFirstNode = NULL;
170 }
171
172 int size() const
173 {
174 return m_iNodeCount;
175 }
176
177 void push_back(const _Tv& value)
178 {
179 m_iNodeCount++;
180
181 Node* pNewNode = new Node();
182 pNewNode->data = value;
183
184 if(m_pFirstNode == NULL)
185 {
186 m_pFirstNode = pNewNode;
187 pNewNode->pPrev = m_pFirstNode;
188 pNewNode->pNext = m_pFirstNode;
189 return;
190 }
191
192 Node* pLastNode = m_pFirstNode->pPrev;
193
194 pLastNode->pNext = pNewNode;
195 m_pFirstNode->pPrev = pNewNode;
196
197 pNewNode->pPrev = pLastNode;
198 pNewNode->pNext = m_pFirstNode;
199 }
200
201 void delete_range(const iterator& beg, const iterator& end)
202 {
203 if(beg == end)
204 throw OdError(OD_T("delete_range() parameters equal"));
205
206 Node* pBeginNode = beg.m_pCurrentNode;
207 Node* pEndNode = end.m_pCurrentNode;
208
209 if(pBeginNode->pNext == pEndNode)
210 {
211 return; // no inner nodes
212 }
213
214 Node* pCurrentNode = pEndNode->pPrev;
215 do
216 {
217 m_iNodeCount--;
218 if(pCurrentNode == m_pFirstNode)
219 m_pFirstNode = pBeginNode;
220
221 pCurrentNode = pCurrentNode->pPrev;
222 delete pCurrentNode->pNext;
223 }
224 while (pCurrentNode != pBeginNode);
225
226 pEndNode->pPrev = pBeginNode;
227 pBeginNode->pNext = pEndNode;
228 }
229
231 {
232 if(empty())
233 throw OdError(OD_T("begin() cannot create iterator for empty cycled list"));
234
235 return iterator(m_pFirstNode);
236 }
237};
238
239
240class OdGeRay3d;
241
242namespace FacetModeler
243{
244
245 class SlicerBaseImpl;
246
248 {
250 {
251 pEdge = NULL;
252 };
253
254 GraphEdgeData(const OdGePoint3d& _st, const OdGePoint3d& _end, const Edge* _pEdge) :
255 st(_st),
256 end(_end),
257 pEdge(_pEdge)
258 {};
259
261 const Edge* pEdge;
262 };
263
265 {
266 struct SegmentPoint
267 {
268 OdGePoint3d pt;
269 double mergeLineParam;
270 OdUInt32 ownerSegmentId;
271
272 SegmentPoint(): mergeLineParam(0.0), ownerSegmentId(0)
273 {}
274
275 SegmentPoint(const OdGePoint3d& point, OdUInt32 segmentId) : mergeLineParam(0.0)
276 {
277 pt = point;
278 ownerSegmentId = segmentId;
279 }
280
281 inline bool operator < ( const SegmentPoint& segPoint ) const
282 {
283 return mergeLineParam < segPoint.mergeLineParam;
284 }
285 };
286 //FELIX_CHANGE_BEGIN
287 //DESKTOP-123542
288 //typedef OdArray<SegmentPoint, OdMemoryAllocator<SegmentPoint> > SegmentPointsArray;
289 using SegmentPointsArray = std::vector< SegmentPoint >;
290 //FELIX_CHANGE_END
291
292 struct SegmentPointLess
293 {
294 inline bool operator() ( const SegmentPoint& pt1, const SegmentPoint& pt2 ) const
295 {
296 return pt1.mergeLineParam < pt2.mergeLineParam;
297 }
298 };
299
300 private:
301 SegmentPointsArray m_segmentPoints;
302 OdGePoint3d m_ptPreviousPoint;
303 OdUInt32Array m_inSegments;
304
305 OdUInt32 m_segmentsIdBase;
306 OdArray<const Edge*> m_segmentTags;
307
308 public:
310 {
311 //FELIX_CHANGE_BEGIN
312 //DESKTOP-123542
313 /*
314 m_segmentPoints.reserve(1024);
315 */
316 //FELIX_CHANGE_END
317 m_segmentsIdBase = 0;
318 }
319
320 void PushSegment(const OdGePoint3d& ptStart, const OdGePoint3d& ptEnd, const Edge* tag = 0)
321 {
322 OdUInt32 segmentId = MakeSegmentId();
323 m_segmentTags.push_back(tag);
324 //FELIX_CHANGE_BEGIN
325 //DESKTOP-123542
326 /*
327 m_segmentPoints.push_back(SegmentPoint(ptStart, segmentId));
328 m_segmentPoints.push_back(SegmentPoint(ptEnd, segmentId));
329 */
330 m_segmentPoints.emplace_back( ptStart, segmentId );
331 m_segmentPoints.emplace_back( ptEnd, segmentId );
332 //FELIX_CHANGE_END
333 }
334
335
337 {
338 if (m_segmentPoints.empty())
339 return;
340
341#ifdef _DEBUG
342 CheckIsAllSegmentsOnMergeLine(mergeLine, tol);
343#endif
344
345 CalculatePointsParamAlongMergeLine(mergeLine, tol);
346 //SortSegmentPointsAlongMergeLine(); // !!!!!!
347 MergeSegments(face_edges, tol);
348 }
349
350
352 {
353 if(m_segmentPoints.empty())
354 return;
355
356 #ifdef _DEBUG
357 CheckIsAllSegmentsOnMergeLine(mergeLine, tol);
358 #endif
359
360 CalculatePointsParamAlongMergeLine(mergeLine, tol);
361 //SortSegmentPointsAlongMergeLine(); // !!!!!!
362 MergeSegments(pGraph, tol);
363 }
364
365 void Clear()
366 {
367 m_segmentPoints.clear();
368 m_segmentsIdBase = 0;
369 m_inSegments.clear();
370 m_segmentTags.clear();
371 }
372
373 private:
374 OdUInt32 MakeSegmentId()
375 {
376 return (m_segmentsIdBase++);
377 }
378
379 #ifdef _DEBUG
380 void CheckIsAllSegmentsOnMergeLine(const OdGeLine3d& mergeLine, const OdGeTol& tol)
381 {
382 for(OdUInt32 iPoint = 0; iPoint < m_segmentPoints.size(); iPoint++)
383 {
384 const SegmentPoint& point = m_segmentPoints[iPoint];
385 //DEBUG_DRAW(point.pt, 0);
386
387 ODA_ASSERT_ONCE(mergeLine.isOn(point.pt, tol));
388 }
389 }
390 #endif
391
392 void CalculatePointsParamAlongMergeLine(const OdGeLine3d& mergeLine, const OdGeTol& tol)
393 {
394 const OdUInt32 pointsCount = m_segmentPoints.size();
395 for(OdUInt32 iPoint = 0; iPoint < pointsCount; iPoint++)
396 {
397 SegmentPoint& point = m_segmentPoints[iPoint];
398 point.mergeLineParam = mergeLine.paramOf(point.pt, tol);
399 }
400 }
401
402 void SortSegmentPointsAlongMergeLine()
403 {
404 std::sort( m_segmentPoints.begin(), m_segmentPoints.end(), SegmentPointLess() );
405 }
406
407 void MergeSegments(SlicerBaseImpl* pGraph, const OdGeTol& tol);
408 void MergeSegments(OdArray<GraphEdgeData>& face_edges, const OdGeTol& tol);
409
410 bool IsOnSegment() const
411 {
412 return (!m_inSegments.empty());
413 }
414
415 bool CanExtractCurrentSegment(const OdGePoint3d& currentPoint, const OdGeTol& tol)
416 {
417 if(!IsOnSegment())
418 return false;
419
420 if(m_ptPreviousPoint.isEqualTo(currentPoint, tol))
421 return false;
422
423 return true;
424 }
425
426 void UpdateInSegmentsArray(OdUInt32 currentPtSegmentId)
427 {
428 if(!m_inSegments.contains(currentPtSegmentId))
429 {
430 m_inSegments.append(currentPtSegmentId);
431 }
432 else
433 {
434 m_inSegments.remove(currentPtSegmentId);
435 }
436 }
437 };
438
439
440 class SlicerBaseImpl : public EdgeGraph
441 {
442 protected:
444 {
446 double m_param;
447 const Edge* m_pEdge;
449
451 {}
452
453 inline bool operator < ( const Intersection& intersection2 ) const {
454 return m_param < intersection2.m_param;
455 }
456 };
458
459 struct ParamLess
460 {
461 inline bool operator() ( const Intersection& intersection1, const Intersection& intersection2 ) const {
462 return intersection1.m_param < intersection2.m_param;
463 }
464 };
465
467 {
469 m_pFace(NULL)
470 {
471 }
472 RayFaceIntersection(const OdGePoint3d& intPt, const Face* pFace) :
473 m_intPt(intPt), m_pFace(pFace)
474 {
475 }
476
478 const Face* m_pFace;
479 };
480
482 {
486 };
487
489 {
493 eExclude*/
494 };
495
497 {
500 const Edge* pEdge;
501 int m_typeExclude; // 0 - not excluded, 1 - start exclude, 2 - end exclude
503 };
505
506 protected:
514
519
523 double m_eq;
524
527
528 std::list<const Face*> m_collectedFaces;
529 std::map<const Edge*, OdGePoint3d> m_collectedIntersectionPts;
530 std::map<const Edge*, VertexInPlanePosition> m_collectedIntersectionFromVertex;
532
533 public:
535
536 void collect_face(const Face* pFace);
537
539
540 // searching ray (face normal) intersections with body faces
541 void checkFaceByRay(const Face* pFace);
542
543 void reserveBuffers( size_t nFaces );
544
545 const OdGeTol& tolerance() const { return m_tol; }
546
547 void setTolerance( const OdGeTol& tol ) { m_tol = tol; }
548
549 void set_cut_plane( const OdGePlane& cutPlane );
550
551 void build_results(Profile2D* pResInclBndry,
552 Profile2D* pResExclCoBndry,
553 Profile2D* pResExclOpBndry,
554 Profile2D* pResExclBndry,
555 FaceConstPtrArray* pCoincidingFaces,
556 FaceConstPtrArray* pOppositeFaces,
557 bool bUseReverseEdgeAtMerge,
558 bool& checkFaceByRay,
559 OdArray<const Edge*>* sourceEdges = 0,
560 const OdGeExtents2d* pIncBox = 0,
561 const OdGeExtents2d* pOrigBox = 0);
562
563 void build_profiles(Profile2D* pResInclBndry,
564 Profile2D* pResExclCoBndry,
565 Profile2D* pResExclOpBndry,
566 Profile2D* pResExclBndry,
567 FaceConstPtrArray* pCoincidingFaces,
568 FaceConstPtrArray* pOppositeFaces,
569 OdArray<const Edge*>* sourceEdges /*= 0*/,
570 const OdGeExtents2d* pBox);
571
574
575 public:
576 void AddEdgeToGraph(const OdGePoint3d& ptStart, const OdGePoint3d& ptEnd, const Edge* tag = 0);
577
578 protected:
579
580 // true - collecting segments
581 // false - checking if face is inside or outside of body
582 bool mode;
583
585
587 const OdGePlane& cut_plane() const;
588
591
594
596
597 bool extractSegment( const OdGePoint3d*& pStart, const OdGePoint3d*& pEnd, bool& bInside );
598
600
602
604
606
607 void exclude_faces( Profile2D& excludedProfile, FaceConstPtrArray& excludeFaces, OdArray<const Edge*>* pSourceEdges = NULL );
608 void exclude_opposite_faces( Profile2D& excludedProfile, FaceConstPtrArray& excludeFaces, OdArray<const Edge*>* pSourceEdges = NULL );
609
611
612 void ClassifyLoopVertices(Edge* pFirstLoopEdge);
614
616
618
620
621 bool ExtractSegmentFromVertex(VtxInPlanePosCycledList::iterator& itBase);
622
623 VtxInPlanePosCycledList::iterator FindOnSegmentStartVertex(VtxInPlanePosCycledList::iterator& itBase);
624
625 VtxInPlanePosCycledList::iterator FindOnSegmentEndVertex(VtxInPlanePosCycledList::iterator& itBase);
626
627 bool VertexOnIntersectionLine(const VtxInPlanePosCycledList::iterator& itVtx) const;
628
629 const OdGePoint3d& VertexPoint(const VtxInPlanePosCycledList::iterator& itVtx) const;
630
631 bool IsIntersectionOnVertex(VtxInPlanePosCycledList::iterator& itVtx);
632
633 bool IsIntersectionOnEdge(VtxInPlanePosCycledList::iterator& itVtx);
634
636
638
639 void AddIntersection(const OdGePoint3d& ptIntersection, const Edge* pEdge, int bOnIntersectionSeg = 0);
640
641 void CollectEdgeForEdgeGraph(const OdGePoint3d& ptStart, const OdGePoint3d& ptEnd, const Edge* tag = 0);
642
644
645 // adding box sidex as edges to graph
647 bool CloseByBox(const OdGeExtents2d& bbox, const OdGeExtents2d& origBBox, bool& checkFaceByRay);
648
649#ifdef _DEBUG
650 void DebugDrawIntersections() const;
651#endif
652 };
653}
654
655#endif //AECSLICERBASEIMPL_H_INCLUDED
#define ODA_ASSERT_ONCE(exp)
Definition: DebugStuff.h:73
tol
Definition: DimVarDefs.h:2287
#define OD_T(x)
unsigned int OdUInt32
void MergeSegmentsAndCollectGraphEdges(const OdGeLine3d &mergeLine, SlicerBaseImpl *pGraph, const OdGeTol &tol, OdArray< GraphEdgeData > &face_edges)
void PushSegment(const OdGePoint3d &ptStart, const OdGePoint3d &ptEnd, const Edge *tag=0)
void MergeSegmentsAndAddToEdgeGraph(const OdGeLine3d &mergeLine, SlicerBaseImpl *pGraph, const OdGeTol &tol)
VtxInPlanePosCycledList::iterator FindOnSegmentStartVertex(VtxInPlanePosCycledList::iterator &itBase)
void AddIntersectionFromEdge(const VertexInPlanePosition &vtxData)
OdArray< RayFaceIntersection > m_rayFaceInters
const OdGeTol & tolerance() const
cycled_list< VertexInPlanePosition > VtxInPlanePosCycledList
std::map< const Edge *, VertexInPlanePosition > m_collectedIntersectionFromVertex
const OdGePlane & current_face_plane() const
bool IsIntersectionOnVertex(VtxInPlanePosCycledList::iterator &itVtx)
SlicerBaseImpl::VertexHalfPlaneSign ClassifyPointAboutIntersectionLine(const OdGePoint3d &ptToClassify, bool exact=false)
void reserveBuffers(size_t nFaces)
void setTolerance(const OdGeTol &tol)
void exclude_opposite_faces(Profile2D &excludedProfile, FaceConstPtrArray &excludeFaces, OdArray< const Edge * > *pSourceEdges=NULL)
VtxInPlanePosCycledList m_classifiedVertices
SlicerBaseImpl::Intersection * FindNextDifferentIntersection(SlicerBaseImpl::Intersection *pIntBase)
SlicerBaseImpl::Intersection * FindIntersectionEnterInside()
void CollectEdgeForEdgeGraph(const OdGePoint3d &ptStart, const OdGePoint3d &ptEnd, const Edge *tag=0)
void AddScaledBoxContour(const OdGeExtents2d &bbox)
std::map< const Edge *, OdGePoint3d > m_collectedIntersectionPts
const OdGePlane & cut_plane() const
IntersResult IntersectCutPlaneToCurrentFacePlane(double tol)
void AddIntersectionFromVertex(const VertexInPlanePosition &vtxData)
VtxInPlanePosCycledList::iterator FindOnSegmentEndVertex(VtxInPlanePosCycledList::iterator &itBase)
void MergeSegmentsAndCollectGraphEdges(OdArray< GraphEdgeData > &face_edges)
void set_cut_plane(const OdGePlane &cutPlane)
bool CloseByBox(const OdGeExtents2d &bbox, const OdGeExtents2d &origBBox, bool &checkFaceByRay)
const FaceConstPtrArray & getCoinciding() const
std::list< const Face * > m_collectedFaces
bool ExtractSegmentFromVertex(VtxInPlanePosCycledList::iterator &itBase)
void exclude_faces(Profile2D &excludedProfile, FaceConstPtrArray &excludeFaces, OdArray< const Edge * > *pSourceEdges=NULL)
bool VertexOnIntersectionLine(const VtxInPlanePosCycledList::iterator &itVtx) const
void checkFaceByRay(const Face *pFace)
bool IsIntersectionOnEdge(VtxInPlanePosCycledList::iterator &itVtx)
const FaceConstPtrArray & getOpposite() const
void ClassifyLoopVertices(Edge *pFirstLoopEdge)
void build_profiles(Profile2D *pResInclBndry, Profile2D *pResExclCoBndry, Profile2D *pResExclOpBndry, Profile2D *pResExclBndry, FaceConstPtrArray *pCoincidingFaces, FaceConstPtrArray *pOppositeFaces, OdArray< const Edge * > *sourceEdges, const OdGeExtents2d *pBox)
IntersResult IntersectCutPlaneToFacePlane(const Face *f) const
bool IntersectionsCoincident(const SlicerBaseImpl::Intersection *pInt1, const SlicerBaseImpl::Intersection *pInt2)
void AddEdgeToGraph(const OdGePoint3d &ptStart, const OdGePoint3d &ptEnd, const Edge *tag=0)
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)
bool extractSegment(const OdGePoint3d *&pStart, const OdGePoint3d *&pEnd, bool &bInside)
const OdGePoint3d & VertexPoint(const VtxInPlanePosCycledList::iterator &itVtx) const
void AddIntersection(const OdGePoint3d &ptIntersection, const Edge *pEdge, int bOnIntersectionSeg=0)
void collect_face(const Face *pFace)
OdArray< Intersection, OdMemoryAllocator< Intersection > > IntersectionArray
void clear()
Definition: OdArray.h:1400
bool empty() const
Definition: OdArray.h:1257
bool contains(const ConstForPtrT &value, size_type start=0) const
Definition: OdArray.h:1524
void push_back(const T &value)
Definition: OdArray.h:1411
size_type append(const T &value)
Definition: OdArray.h:1725
bool remove(const T &value, size_type start=0)
Definition: OdArray.h:2309
double paramOf(const OdGePoint3d &point, const OdGeTol &tol=OdGeContext::gTol) const
bool isOn(const OdGePlane &plane, const OdGeTol &tol=OdGeContext::gTol) const
bool isEqualTo(const OdGePoint3d &point, const OdGeTol &tol=OdGeContext::gTol) const
Definition: GeTol.h:49
iterator(const iterator &it)
bool operator==(const iterator &it) const
bool operator!=(const iterator &it) const
const _Tv & data() const
void delete_range(const iterator &beg, const iterator &end)
int size() const
void push_back(const _Tv &value)
bool empty() const
GLfloat f
Definition: gles2_ext.h:564
GLint GLenum GLsizei GLsizei GLint GLsizei const void * data
Definition: gles2_ext.h:110
GLsizei const GLfloat * value
Definition: gles2_ext.h:302
GraphEdgeData(const OdGePoint3d &_st, const OdGePoint3d &_end, const Edge *_pEdge)
bool operator<(const Intersection &intersection2) const
bool operator()(const Intersection &intersection1, const Intersection &intersection2) const
RayFaceIntersection(const OdGePoint3d &intPt, const Face *pFace)