1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 // This file is part of Open CASCADE Technology software library.
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
18 #include <BOPAlgo_PaveFiller.ixx>
20 #include <NCollection_IncAllocator.hxx>
22 #include <TopoDS_Vertex.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Face.hxx>
26 #include <BRepBndLib.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom2d_Curve.hxx>
37 #include <BOPCol_NCVector.hxx>
38 #include <BOPCol_TBB.hxx>
40 #include <BOPTools_AlgoTools.hxx>
41 #include <BOPTools_AlgoTools2D.hxx>
43 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
44 #include <BOPDS_ListOfPaveBlock.hxx>
45 #include <BOPDS_PaveBlock.hxx>
46 #include <BOPDS_CommonBlock.hxx>
47 #include <BOPDS_Pave.hxx>
48 #include <BOPDS_ShapeInfo.hxx>
49 #include <BOPDS_MapOfPaveBlock.hxx>
50 #include <BOPDS_VectorOfInterfFF.hxx>
51 #include <BOPDS_Interf.hxx>
52 #include <BOPDS_VectorOfCurve.hxx>
53 #include <BOPDS_VectorOfFaceInfo.hxx>
54 #include <BOPDS_FaceInfo.hxx>
55 #include <BOPDS_MapOfPaveBlock.hxx>
56 #include <BOPDS_Curve.hxx>
59 static void UpdateVertices(const TopoDS_Edge& aE,
60 const TopoDS_Face& aF);
62 //=======================================================================
63 //class : BOPAlgo_SplitEdge
65 //=======================================================================
66 class BOPAlgo_SplitEdge {
73 ~BOPAlgo_SplitEdge() {
76 void SetData(const TopoDS_Edge& aE,
77 const TopoDS_Vertex& aV1,
78 const Standard_Real aT1,
79 const TopoDS_Vertex& aV2,
80 const Standard_Real aT2) {
89 void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
93 Handle(BOPDS_PaveBlock)& PaveBlock() {
97 void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) {
101 Handle(BOPDS_CommonBlock)& CommonBlock() {
105 const TopoDS_Edge& SplitEdge() const {
109 const Bnd_Box Box() {
114 BOPTools_AlgoTools::MakeSplitEdge(myE,
118 BRepBndLib::Add(myESp, myBox);
129 Handle(BOPDS_PaveBlock) myPB;
130 Handle(BOPDS_CommonBlock) myCB;
136 //=======================================================================
137 typedef BOPCol_NCVector
138 <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge;
140 typedef BOPCol_TBBFunctor
142 BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor;
144 typedef BOPCol_TBBCnt
145 <BOPAlgo_SplitEdgeFunctor,
146 BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeCnt;
148 //=======================================================================
149 // function: MakeSplitEdges
151 //=======================================================================
152 void BOPAlgo_PaveFiller::MakeSplitEdges()
154 Standard_Integer aNbPBP;
158 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
159 aNbPBP=aPBP.Extent();
164 Standard_Boolean bCB, bV1, bV2;
165 Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
166 Standard_Real aT1, aT2;
167 BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
168 Handle(BOPDS_PaveBlock) aPB;
169 BOPDS_MapOfPaveBlock aMPB(100);
170 TopoDS_Vertex aV1, aV2;
172 BOPAlgo_VectorOfSplitEdge aVBSE;
175 for (i=0; i<aNbPBP; ++i) {
176 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
181 aPB->Indices(nV1, nV2);
182 bV1=myDS->IsNewShape(nV1);
183 bV2=myDS->IsNewShape(nV2);
186 nE=aPB->OriginalEdge();
192 aItPB.Initialize(aLPB);
193 for (; aItPB.More(); aItPB.Next()) {
195 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
198 myDS->SortPaveBlocks(aCB);
199 aPB=aCB->PaveBlock1();
203 nE=aPB->OriginalEdge();
204 aPB->Indices(nV1, nV2);
205 aPB->Range(aT1, aT2);
207 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
208 aE.Orientation(TopAbs_FORWARD);
210 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
211 aV1.Orientation(TopAbs_FORWARD);
213 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
214 aV2.Orientation(TopAbs_REVERSED);
216 BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
218 aBSE.SetData(aE, aV1, aT1, aV2, aT2);
219 aBSE.SetPaveBlock(aPB);
221 aBSE.SetCommonBlock(aCB);
224 } // for (; aItPB.More(); aItPB.Next()) {
225 } // for (i=0; i<aNbPBP; ++i) {
227 aNbVBSE=aVBSE.Extent();
228 //======================================================
229 BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE);
230 //======================================================
234 aSI.SetShapeType(TopAbs_EDGE);
236 for (k=0; k < aNbVBSE; ++k) {
237 BOPAlgo_SplitEdge& aBSE=aVBSE(k);
239 const TopoDS_Edge& aSp=aBSE.SplitEdge();
240 const Bnd_Box& aBox=aBSE.Box();
242 Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
243 Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
246 aSI.ChangeBox()=aBox;
248 nSp=myDS->Append(aSI);
250 if (!aCBk.IsNull()) {
258 //=======================================================================
259 // function: SplitEdge
261 //=======================================================================
262 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE,
263 const Standard_Integer nV1,
264 const Standard_Real aT1,
265 const Standard_Integer nV2,
266 const Standard_Real aT2)
268 Standard_Integer nSp;
269 TopoDS_Vertex aV1, aV2;
273 aSI.SetShapeType(TopAbs_EDGE);
275 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
276 aE.Orientation(TopAbs_FORWARD);
278 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
279 aV1.Orientation(TopAbs_FORWARD);
281 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
282 aV2.Orientation(TopAbs_REVERSED);
284 BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
288 Bnd_Box& aBox=aSI.ChangeBox();
289 BRepBndLib::Add(aSp, aBox);
291 nSp=myDS->Append(aSI);
294 //=======================================================================
295 // function: MakePCurves
297 //=======================================================================
298 void BOPAlgo_PaveFiller::MakePCurves()
300 Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI;
301 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
302 BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
303 TopoDS_Face aF1F, aF2F;
307 // 1. Process Common Blocks
308 const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
311 for (i=0; i<aNbFI; ++i) {
312 const BOPDS_FaceInfo& aFI=aFIP(i);
315 aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
316 aF1F.Orientation(TopAbs_FORWARD);
318 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
319 aItMPB.Initialize(aMPBIn);
320 for(; aItMPB.More(); aItMPB.Next()) {
321 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
323 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
325 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
328 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
329 aItMPB.Initialize(aMPBOn);
330 for(; aItMPB.More(); aItMPB.Next()) {
331 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
332 if (myDS->IsCommonBlockOnEdge(aPB)) {
334 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
336 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
341 if (!mySectionAttribute.PCurveOnS1() &&
342 !mySectionAttribute.PCurveOnS2()) {
346 // 2. Process section edges
347 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
349 for (i=0; i<aNbFF; ++i) {
350 const BOPDS_InterfFF& aFF=aFFs(i);
351 aFF.Indices(nF1, nF2);
353 aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
354 aF1F.Orientation(TopAbs_FORWARD);
355 aF2F=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
356 aF2F.Orientation(TopAbs_FORWARD);
358 const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
360 for (k=0; k<aNbC; ++k) {
361 const BOPDS_Curve& aNC=aVNC(k);
362 const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
363 aItLPB.Initialize(aLPB);
364 for(; aItLPB.More(); aItLPB.Next()) {
365 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
367 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
369 if (mySectionAttribute.PCurveOnS1()) {
370 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F);
371 UpdateVertices(aE, aF1F);
374 if (mySectionAttribute.PCurveOnS2()) {
375 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF2F);
376 UpdateVertices(aE, aF2F);
382 //=======================================================================
383 // function: RefineFaceInfoOn
385 //=======================================================================
386 void BOPAlgo_PaveFiller::RefineFaceInfoOn()
388 Standard_Integer aNbPBP;
392 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
393 aNbPBP=aPBP.Extent();
398 Standard_Boolean bV1, bV2;
399 Standard_Integer i, nV1, nV2, aNbPB;
400 Handle(BOPDS_PaveBlock) aPB;
402 for (i=0; i<aNbPBP; ++i) {
403 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
408 aPB->Indices(nV1, nV2);
409 bV1=myDS->IsNewShape(nV1);
410 bV2=myDS->IsNewShape(nV2);
413 if (!myDS->IsCommonBlock(aPB)) {
414 // the PB seems to be untouced
418 }//if (!(bV1 || bV2)) {
420 }//for (i=0; i<aNbPBP; ++i) {
421 myDS->RefineFaceInfoOn();
423 //=======================================================================
424 //function : UpdateVertices
425 //purpose : update tolerances of vertices comparing extremities of
427 //=======================================================================
428 void UpdateVertices(const TopoDS_Edge& aE,
429 const TopoDS_Face& aF)
432 Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
435 Handle(Geom_Surface) aS;
436 Handle(Geom_Curve) aC3D;
437 Handle(Geom2d_Curve) aC2D;
443 aEf.Orientation(TopAbs_FORWARD);
445 TopExp::Vertices(aEf, aV[0], aV[1]);
447 aS=BRep_Tool::Surface(aF);
448 aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
449 aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
451 for (j=0; j<2; ++j) {
452 aTolV2=BRep_Tool::Tolerance(aV[j]);
453 aTolV2=aTolV2*aTolV2;
455 aC3D->D0(aT[j], aP3D);
456 aC2D->D0(aT[j], aP2Dx);
457 aP2Dx.Coord(aUx, aVx);
458 aS->D0(aUx, aVx, aP3Dx);
459 aD2=aP3D.SquareDistance(aP3Dx);
462 aBB.UpdateVertex(aV[j], aD);