1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: NMTTools_DEProcessor.cxx
24 // Created: Wed Sep 12 12:10:52 2001
25 // Author: Peter KURNEV
28 #include <NMTTools_DEProcessor.ixx>
30 #include <Precision.hxx>
32 #include <TColStd_ListIteratorOfListOfInteger.hxx>
33 #include <TColStd_ListOfInteger.hxx>
35 #include <gp_Pnt2d.hxx>
37 #include <gp_Lin2d.hxx>
41 #include <Geom2d_Curve.hxx>
42 #include <Geom2d_Line.hxx>
43 #include <Geom2d_TrimmedCurve.hxx>
44 #include <Geom2dAdaptor_Curve.hxx>
45 #include <Geom2dInt_GInter.hxx>
47 #include <IntRes2d_IntersectionPoint.hxx>
49 #include <TopoDS_Shape.hxx>
50 #include <TopoDS_Edge.hxx>
52 #include <TopoDS_Face.hxx>
53 #include <TopoDS_Vertex.hxx>
54 #include <TopoDS_Solid.hxx>
57 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
58 #include <TopTools_ListOfShape.hxx>
59 #include <TopTools_ListIteratorOfListOfShape.hxx>
61 #include <BRep_Tool.hxx>
62 #include <BRep_Builder.hxx>
64 #include <BRepAdaptor_Surface.hxx>
66 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
68 #include <IntTools_Tools.hxx>
69 #include <IntTools_Context.hxx>
71 #include <BOPTools_DEInfo.hxx>
72 #include <BOPTools_Pave.hxx>
73 #include <BOPTools_ListOfPave.hxx>
74 #include <BOPTools_ListIteratorOfListOfPave.hxx>
75 #include <BOPTools_PaveBlock.hxx>
76 #include <BOPTools_ListOfPaveBlock.hxx>
77 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
78 #include <BOPTools_PaveBlockIterator.hxx>
79 #include <BOPTools_SSInterference.hxx>
80 #include <BOPTools_PavePool.hxx>
81 #include <BOPTools_PaveSet.hxx>
82 #include <BOPTools_Tools3D.hxx>
83 #include <BOPTools_SequenceOfCurves.hxx>
84 #include <BOPTools_Curve.hxx>
85 #include <BOPTools_CArray1OfSSInterference.hxx>
86 #include <BOPTools_SplitShapesPool.hxx>
88 #include <NMTDS_ShapesDataStructure.hxx>
89 #include <NMTDS_InterfPool.hxx>
91 #include <NMTTools_PaveFiller.hxx>
93 //=======================================================================
96 //=======================================================================
97 NMTTools_DEProcessor::NMTTools_DEProcessor(NMTTools_PaveFiller& aPaveFiller)
99 myIsDone(Standard_False)
101 myFiller=(NMTTools_PaveFiller*) &aPaveFiller;
104 //=======================================================================
107 //=======================================================================
108 Standard_Boolean NMTTools_DEProcessor::IsDone() const
112 //=======================================================================
115 //=======================================================================
116 void NMTTools_DEProcessor::Do()
118 Standard_Integer aNbE;
120 myIsDone=Standard_False;
122 FindDegeneratedEdges();
124 aNbE=myDEMap.Extent();
132 //=======================================================================
133 // function: FindDegeneratedEdges
135 //=======================================================================
136 void NMTTools_DEProcessor::FindDegeneratedEdges()
138 Standard_Integer i, aNb, nV, nF, nVx, ip, iRankE;
140 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
142 aNb=myDS->NumberOfShapesOfTheObject();
143 for (i=1; i<=aNb; ++i) {
144 const TopoDS_Shape aF=myDS->Shape(i);
145 if (aF.ShapeType()==TopAbs_FACE) {
146 TopExp::MapShapesAndAncestors (aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
150 for (i=1; i<=aNb; ++i) {
151 const TopoDS_Shape aS=myDS->Shape(i);
152 if (aS.ShapeType()==TopAbs_EDGE) {
153 const TopoDS_Edge& aE=TopoDS::Edge(aS);
155 if (BRep_Tool::Degenerated(aE)) {
156 iRankE=myDS->Rank(i);
157 aV=TopExp::FirstVertex(aE);
158 nVx=myDS->ShapeIndex(aV, iRankE);
161 ip=myFiller->FindSDVertex(nV);
166 TColStd_ListOfInteger aLFn;
167 const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
168 TopTools_ListIteratorOfListOfShape anIt(aLF);
169 for (; anIt.More(); anIt.Next()) {
170 const TopoDS_Shape& aF=anIt.Value();
171 nF=myDS->ShapeIndex(aF, iRankE);
174 BOPTools_DEInfo aDEInfo;
175 aDEInfo.SetVertex(nV);
176 aDEInfo.SetFaces(aLFn);
178 myDEMap.Add (i, aDEInfo);
183 //=======================================================================
186 //=======================================================================
187 void NMTTools_DEProcessor::DoPaves()
190 Standard_Integer i, aNbE, nED, nVD, aNbLPB, nFD;
193 aNbE=myDEMap.Extent();
194 for (i=1; i<=aNbE; ++i) {
195 nED=myDEMap.FindKey(i);
197 const BOPTools_DEInfo& aDEInfo=myDEMap(i);
198 nVD=aDEInfo.Vertex();
200 // Fill PaveSet for the edge nED
201 const TColStd_ListOfInteger& nLF=aDEInfo.Faces();
202 TColStd_ListIteratorOfListOfInteger anIt(nLF);
203 for (; anIt.More(); anIt.Next()) {
206 BOPTools_ListOfPaveBlock aLPB;
207 FindPaveBlocks(nED, nVD, nFD, aLPB);
209 aNbLPB=aLPB.Extent();
214 FillPaveSet (nED, nVD, nFD, aLPB);
217 // Fill aSplitEdges for the edge nED
218 FillSplitEdgesPool(nED);
221 MakeSplitEdges(nED, nFD);
225 //=======================================================================
226 // function: FindPaveBlocks
228 //=======================================================================
229 void NMTTools_DEProcessor::FindPaveBlocks(const Standard_Integer ,
230 const Standard_Integer nVD,
231 const Standard_Integer nFD,
232 BOPTools_ListOfPaveBlock& aLPBOut)
234 BOPTools_ListIteratorOfListOfPaveBlock anIt;
235 Standard_Integer i, aNb, nF2, nV;
237 BOPTools_CArray1OfSSInterference& aFFs=(myFiller->IP())->SSInterferences();
240 for (i=1; i<=aNb; ++i) {
241 BOPTools_SSInterference& aFF=aFFs(i);
243 nF2=aFF.OppositeIndex(nFD);
249 const BOPTools_ListOfPaveBlock& aLPBSplits=aFF.PaveBlocks();
250 anIt.Initialize(aLPBSplits);
251 for (; anIt.More(); anIt.Next()) {
252 const BOPTools_PaveBlock& aPBSp=anIt.Value();
254 const BOPTools_Pave& aPave1=aPBSp.Pave1();
257 aLPBOut.Append(aPBSp);
261 const BOPTools_Pave& aPave2=aPBSp.Pave2();
264 aLPBOut.Append(aPBSp);
270 Standard_Integer j, aNbCurves;
272 BOPTools_SequenceOfCurves& aSC=aFF.Curves();
273 aNbCurves=aSC.Length();
274 for (j=1; j<=aNbCurves; ++j) {
275 const BOPTools_Curve& aBC=aSC(j);
276 const BOPTools_ListOfPaveBlock& aLPBSe=aBC.NewPaveBlocks();
278 anIt.Initialize(aLPBSe);
279 for (; anIt.More(); anIt.Next()) {
280 const BOPTools_PaveBlock& aPBSe=anIt.Value();
282 const BOPTools_Pave& aPv1=aPBSe.Pave1();
285 aLPBOut.Append(aPBSe);
289 const BOPTools_Pave& aPv2=aPBSe.Pave2();
292 aLPBOut.Append(aPBSe);
299 //=======================================================================
300 // function: FillPaveSet
302 //=======================================================================
303 void NMTTools_DEProcessor::FillPaveSet (const Standard_Integer nED,
304 const Standard_Integer nVD,
305 const Standard_Integer nFD,
306 const BOPTools_ListOfPaveBlock& aLPB)
308 Standard_Boolean bIsDone, bXDir, bRejectFlag;
309 Standard_Integer nE, aNbPoints, j;
310 Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT, aXx;
311 gp_Pnt2d aP2d1, aP2d2, aP2D;
314 aDT=Precision::PConfusion();
316 BOPTools_PaveSet& aPaveSet=
317 (myFiller->ChangePavePool()).ChangeValue(myDS->RefEdge(nED));
319 // Clear aPaveSet, aSplitEdges
320 aPaveSet.ChangeSet().Clear();
322 const TopoDS_Edge aDE=TopoDS::Edge(myDS->Shape(nED));
323 const TopoDS_Face aDF=TopoDS::Face(myDS->Shape(nFD));
325 // 2D Curve of degenerated edge on the face aDF
326 Handle(Geom2d_Curve) aC2DDE1=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2);
327 Handle(Geom2d_TrimmedCurve)aC2DDE=new Geom2d_TrimmedCurve(aC2DDE1, aTD1, aTD2);
329 // Choose direction for degenerated edge
330 aC2DDE->D0(aTD1, aP2d1);
331 aC2DDE->D0(aTD2, aP2d2);
333 bXDir=Standard_False;
334 if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){
338 // Prepare bounding Paves
339 BOPTools_Pave aPave1 (nVD, aTD1, BooleanOperations_UnknownInterference);
340 aPaveSet.Append(aPave1);
341 BOPTools_Pave aPave2 (nVD, aTD2, BooleanOperations_UnknownInterference);
342 aPaveSet.Append(aPave2);
345 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
346 for (; anIt.More(); anIt.Next()) {
347 const BOPTools_PaveBlock& aPB=anIt.Value();
349 const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));
351 Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2);
354 Geom2dAdaptor_Curve aGAC1, aGAC2;
356 aGAC1.Load(aC2DDE, aTD1, aTD2);
357 Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D);
358 if (!aL2D.IsNull()) {
362 aGAC2.Load(aC2D, aT1, aT2);
366 Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter);
367 bIsDone=aGInter.IsDone();
369 aNbPoints=aGInter.NbPoints();
371 for (j=1; j<=aNbPoints; ++j) {
372 aP2D=aGInter.Point(j).Value();
373 Handle(Geom2d_Line) aCLDE;
375 //modified by NIZNHY-PKV Thu Mar 20 17:37:32 2008f
376 Handle(Geom2d_TrimmedCurve) aCLDET1=
377 Handle(Geom2d_TrimmedCurve)::DownCast(aC2DDE1);
378 if (aCLDET1.IsNull()) {
379 aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1);
382 Handle(Geom2d_Curve) aBasisCurve=aCLDET1->BasisCurve();
383 aCLDE=Handle(Geom2d_Line)::DownCast(aBasisCurve);
385 //aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1);
386 //modified by NIZNHY-PKV Thu Mar 20 17:37:37 2008t
388 if (aCLDE.IsNull()) {
393 aX=ElCLib::Parameter(aLDE, aP2D);
395 if (fabs (aX-aTD1) < aDT || fabs (aX-aTD2) < aDT) {
398 if (aX < aTD1 || aX > aTD2) {
402 bRejectFlag=Standard_False;
403 const BOPTools_ListOfPave& aListOfPave=aPaveSet.Set();
404 BOPTools_ListIteratorOfListOfPave aPaveIt(aListOfPave);
405 for (; aPaveIt.More(); aPaveIt.Next()) {
406 const BOPTools_Pave& aPavex=aPaveIt.Value();
408 if (fabs (aX-aXx) < aDT) {
409 bRejectFlag=Standard_True;
417 BOPTools_Pave aPave(nVD, aX, BooleanOperations_UnknownInterference);
418 aPaveSet.Append(aPave);
424 //=======================================================================
425 // function: FillSplitEdgesPool
427 //=======================================================================
428 void NMTTools_DEProcessor::FillSplitEdgesPool (const Standard_Integer nED)
430 BOPTools_SplitShapesPool& aSplitShapesPool=
431 myFiller->ChangeSplitShapesPool();
432 BOPTools_ListOfPaveBlock& aSplitEdges=
433 aSplitShapesPool.ChangeValue(myDS->RefEdge(nED));
437 const BOPTools_PavePool& aPavePool=myFiller->PavePool();
438 BOPTools_PavePool* pPavePool=(BOPTools_PavePool*) &aPavePool;
439 BOPTools_PaveSet& aPaveSet= pPavePool->ChangeValue(myDS->RefEdge(nED));
441 BOPTools_PaveBlockIterator aPBIt(nED, aPaveSet);
442 for (; aPBIt.More(); aPBIt.Next()) {
443 BOPTools_PaveBlock& aPB=aPBIt.Value();
444 aSplitEdges.Append(aPB);
447 //=======================================================================
448 // function: MakeSplitEdges
450 //=======================================================================
451 void NMTTools_DEProcessor::MakeSplitEdges (const Standard_Integer nED,
452 const Standard_Integer nFD)
454 const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
455 const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nED));
457 Standard_Integer nV1, nV2, aNbPB, aNewShapeIndex;
458 Standard_Real t1, t2;
459 TopoDS_Edge aE, aESplit;
460 TopoDS_Vertex aV1, aV2;
461 BOPTools_ListIteratorOfListOfPaveBlock aPBIt;
463 const TopoDS_Edge aDE=TopoDS::Edge(myDS->Shape(nED));
464 const TopoDS_Face aDF=TopoDS::Face(myDS->Shape(nFD));
466 //modified by NIZNHY-PKV Wed Oct 20 13:20:37 2010f
467 aNbPB=aSplitEdges.Extent();
469 Standard_Real aT1, aT2, dT1, dT2, aDT;
470 Handle(Geom2d_Curve) aC2D;
472 BOPTools_PaveBlock& aPB=aSplitEdges.First();
474 const BOPTools_Pave& aPave1=aPB.Pave1();
476 const BOPTools_Pave& aPave2=aPB.Pave2();
480 aV1=*((TopoDS_Vertex*)&myDS->GetShape(nV1));
482 aV2=TopExp::FirstVertex(aDE);
483 if (aV2.IsSame(aV1)) {
484 aC2D=BRep_Tool::CurveOnSurface(aDE, aDF, aT1, aT2);
494 aDT=Precision::PConfusion();
495 if(dT1<aDT && dT2<aDT) {
496 BOPTools_ListOfPaveBlock* pLPB=(BOPTools_ListOfPaveBlock*)&aSplitEdges;
502 //modified by NIZNHY-PKV Wed Oct 20 13:20:39 2010t
504 aPBIt.Initialize(aSplitEdges);
505 for (; aPBIt.More(); aPBIt.Next()) {
506 BOPTools_PaveBlock& aPB=aPBIt.Value();
508 const BOPTools_Pave& aPave1=aPB.Pave1();
511 aV1=TopoDS::Vertex(myDS->GetShape(nV1));
512 aV1.Orientation(TopAbs_FORWARD);
514 const BOPTools_Pave& aPave2=aPB.Pave2();
517 aV2=TopoDS::Vertex(myDS->GetShape(nV2));
518 aV2.Orientation(TopAbs_REVERSED);
520 MakeSplitEdge(aDE, aDF, aV1, t1, aV2, t2, aESplit);
522 // Add Split Part of the Original Edge to the DS
523 BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
525 anASSeq.SetNewSuccessor(nV1);
526 anASSeq.SetNewOrientation(aV1.Orientation());
528 anASSeq.SetNewSuccessor(nV2);
529 anASSeq.SetNewOrientation(aV2.Orientation());
531 myDS->InsertShapeAndAncestorsSuccessors(aESplit, anASSeq);
532 aNewShapeIndex=myDS->NumberOfInsertedShapes();
533 myDS->SetState(aNewShapeIndex, BooleanOperations_UNKNOWN);
535 // Fill Split Set for the Original Edge
536 aPB.SetEdge(aNewShapeIndex);
540 //=======================================================================
541 // function: MakeSplitEdge
543 //=======================================================================
544 void NMTTools_DEProcessor::MakeSplitEdge (const TopoDS_Edge& aE,
545 const TopoDS_Face& aF,
546 const TopoDS_Vertex& aV1,
547 const Standard_Real aP1,
548 const TopoDS_Vertex& aV2,
549 const Standard_Real aP2,
550 TopoDS_Edge& aNewEdge)
552 Standard_Real aTol=1.e-7;
561 BB.Range(E, aF, aP1, aP2);
563 BB.Degenerated(E, Standard_True);
565 BB.UpdateEdge(E, aTol);