1 // Copyright (C) 2007-2008 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
22 // File: NMTAlgo_Inter3d.cxx
23 // Created: Tue Jan 27 15:14:13 2004
24 // Author: Peter KURNEV
27 #include <NMTAlgo_Builder.ixx>
29 #include <TColStd_IndexedMapOfInteger.hxx>
31 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Compound.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopoDS_Shape.hxx>
38 #include <TopExp_Explorer.hxx>
40 #include <BRep_Builder.hxx>
41 #include <BRep_Tool.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
44 #include <TopTools_ListOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <BOPTColStd_Dump.hxx>
48 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
50 #include <IntTools_Context.hxx>
52 #include <BOPTools_Tools3D.hxx>
53 #include <BOPTools_CArray1OfSSInterference.hxx>
54 #include <BOPTools_InterferencePool.hxx>
55 #include <BOPTools_SSInterference.hxx>
56 #include <BOPTools_SequenceOfCurves.hxx>
57 #include <BOPTools_Curve.hxx>
58 #include <BOPTools_SequenceOfCurves.hxx>
59 #include <BOPTools_SplitShapesPool.hxx>
60 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
61 #include <BOPTools_ListOfPaveBlock.hxx>
62 #include <BOPTools_PaveBlock.hxx>
64 #include <BOP_WireEdgeSet.hxx>
65 #include <BOP_FaceBuilder.hxx>
66 #include <BOP_BuilderTools.hxx>
68 #include <NMTDS_ShapesDataStructure.hxx>
70 #include <NMTTools_PaveFiller.hxx>
71 #include <NMTTools_ListOfCoupleOfShape.hxx>
72 #include <NMTTools_Tools.hxx>
73 #include <NMTTools_CoupleOfShape.hxx>
74 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
75 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
77 #include <TopoDS_Shell.hxx>
78 #include <NMTAlgo_Tools.hxx>
79 #include <TColStd_IndexedMapOfInteger.hxx>
80 #include <TopExp_Explorer.hxx>
81 #include <TopoDS_Iterator.hxx>
83 //=======================================================================
84 // function: NMTAlgo_Inter3d::NMTAlgo_Inter3d()
86 //=======================================================================
87 NMTAlgo_Builder::NMTAlgo_Builder()
92 //=======================================================================
93 // function: ~NMTAlgo_Builder
95 //=======================================================================
96 NMTAlgo_Builder::~NMTAlgo_Builder()
100 //=======================================================================
103 //=======================================================================
104 void NMTAlgo_Builder::Clear()
106 NMTAlgo_Algo::Clear();
108 myImagesEdges.Clear();
109 myImagesFaces.Clear();
111 mySectionParts.Clear();
114 //=======================================================================
115 // function: ComputeWithFiller
117 //=======================================================================
118 void NMTAlgo_Builder::ComputeWithFiller(const NMTTools_DSFiller& aDSF)
121 myIsDone=Standard_False;
132 //=======================================================================
133 // function: FillSDFaces
135 //=======================================================================
136 void NMTAlgo_Builder::FillSDFaces()
138 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
139 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
140 BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
141 BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
142 IntTools_Context& aCtx= pPF->ChangeContext();
144 Standard_Boolean bIsSDF;
145 Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC;
146 TopTools_ListIteratorOfListOfShape aItF1, aItF2;
147 NMTTools_ListOfCoupleOfShape aLCS;
151 // 1. For each FF find among images of faces
152 // all pairs of same domain faces (SDF) [=> aLCS]
154 for (i=1; i<=aNbFF; ++i) {
155 BOPTools_SSInterference& aFF=aFFs(i);
156 aFF.Indices(nF1, nF2);
158 const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
159 const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
161 // if there are no in/on 2D split parts the faces nF1, nF2
163 const BOPTools_ListOfPaveBlock& aLPBInOn=aFF.PaveBlocks();
164 aNbPBInOn=aLPBInOn.Extent();
169 // if there is at least one section edge between faces nF1, nF2
170 // they can not be SDF
171 BOPTools_SequenceOfCurves& aSC=aFF.Curves();
177 // the faces are suspected to be SDF.
178 // Try to find SDF among images of nF1, nF2
179 const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
180 const TopTools_ListOfShape& aLF2=myImagesFaces.Image(aF2);
182 aItF1.Initialize(aLF1);
183 for (; aItF1.More(); aItF1.Next()) {
184 const TopoDS_Face& aF1x=TopoDS::Face(aItF1.Value());
186 aItF2.Initialize(aLF2);
187 for (; aItF2.More(); aItF2.Next()) {
188 const TopoDS_Face& aF2y=TopoDS::Face(aItF2.Value());
189 bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx);
191 NMTTools_CoupleOfShape aCS;
199 }//for (i=1; i<=aNbFF; ++i)
207 NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;
209 NMTTools_Tools::FindChains(aLCS, aMC);
211 // 3. Fill the map of SDF mySDFaces
213 for (i=1; i<=aNbC; ++i) {
214 const TopoDS_Shape& aF=aMC.FindKey(i);
215 const TopTools_IndexedMapOfShape& aMSDF=aMC(i);
217 aNbFF=aMSDF.Extent();
218 for (j=1; j<=aNbFF; ++j) {
219 const TopoDS_Shape& aFSD=aMSDF(j);
220 mySDFaces.Add(aFSD, aF);
225 //=======================================================================
226 // function: FillImagesFaces
228 //=======================================================================
229 void NMTAlgo_Builder::FillImagesFaces()
231 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
232 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
233 IntTools_Context& aCtx= pPF->ChangeContext();
235 Standard_Integer i, j, aNb, aNbE;
236 TopTools_IndexedMapOfShape aMFence, aME;
237 TColStd_IndexedMapOfInteger aMFP;
239 // 1. Select Faces to process (MFP)
240 aNb=aDS.NumberOfShapesOfTheObject();
241 for (i=1; i<=aNb; ++i) {
242 const TopoDS_Shape& aF=aDS.Shape(i);
243 if (aF.ShapeType()!=TopAbs_FACE) {
246 if (aMFence.Contains(aF)) {
251 if (myIn2DParts.Contains(aF)) {
256 if (mySectionParts.Contains(aF)) {
262 TopExp::MapShapes(aF, TopAbs_EDGE, aME);
265 for(j=1; j<=aNbE; ++j) {
266 const TopoDS_Shape& aE=aME(j);
268 if (myImagesEdges.HasImage(aE)) {
273 }// for (i=1; i<=aNb; ++i)
276 Standard_Boolean bToReverse, bIsClosed, bIsDegenerated;
277 Standard_Integer aNbF, nF;
280 TopExp_Explorer anExp;
281 TopTools_ListIteratorOfListOfShape aIt;
282 BRepAlgo_Image aImagesFaces;
283 TopAbs_Orientation anOriF;
286 for (i=1; i<=aNbF; ++i) {
288 const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF));
289 anOriF=aF.Orientation();
291 aFF.Orientation(TopAbs_FORWARD);
296 BOP_WireEdgeSet aWES;
297 aWES.Initialize(aFF);
299 // 2.1.1. Add Split parts
300 anExp.Init(aFF, TopAbs_EDGE);
301 for (; anExp.More(); anExp.Next()) {
302 const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
304 if (!myImagesEdges.HasImage(aE)) {
305 aWES.AddStartElement(aE);
309 bIsDegenerated=BRep_Tool::Degenerated(aE);
310 bIsClosed=BRep_Tool::IsClosed(aE, aF);
312 const TopTools_ListOfShape& aLIE=myImagesEdges.Image(aE);
313 aIt.Initialize(aLIE);
314 for (; aIt.More(); aIt.Next()) {
315 aSp=TopoDS::Edge(aIt.Value());
317 if (bIsDegenerated) {
318 aSp.Orientation(aE.Orientation());
319 aWES.AddStartElement(aSp);
324 if (!aMFence.Contains(aSp)){
327 if (!BRep_Tool::IsClosed(aSp, aF)){
328 BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
331 aSp.Orientation(TopAbs_FORWARD);
332 aWES.AddStartElement(aSp);
334 aSp.Orientation(TopAbs_REVERSED);
335 aWES.AddStartElement(aSp);
340 bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
344 aWES.AddStartElement(aSp);
348 // 2.1.2. Add In2D Parts
349 if (myIn2DParts.Contains(aF)) {
350 const TopTools_ListOfShape& aLE=myIn2DParts.FindFromKey(aF);
352 for (; aIt.More(); aIt.Next()) {
353 aSp=TopoDS::Edge(aIt.Value());
355 aSp.Orientation(TopAbs_FORWARD);
356 aWES.AddStartElement(aSp);
358 aSp.Orientation(TopAbs_REVERSED);
359 aWES.AddStartElement(aSp);
363 // 2.1.3. Add Section Parts
364 if (mySectionParts.Contains(aF)) {
365 const TopTools_ListOfShape& aLE=mySectionParts.FindFromKey(aF);
367 for (; aIt.More(); aIt.Next()) {
368 aSp=TopoDS::Edge(aIt.Value());
370 aSp.Orientation(TopAbs_FORWARD);
371 aWES.AddStartElement(aSp);
373 aSp.Orientation(TopAbs_REVERSED);
374 aWES.AddStartElement(aSp);
378 // 2.2. Build images Faces
381 aFB.SetTreatment(0); // 0-Do Internal Edges
382 aFB.SetTreatSDScales(0); // what is 0 ??
386 TopTools_ListOfShape aLFR;
388 const TopTools_ListOfShape& aLF=aFB.NewFaces();
391 for (; aIt.More(); aIt.Next()) {
392 TopoDS_Shape& aFR=aIt.Value();
393 if (anOriF==TopAbs_REVERSED) {
394 aFR.Orientation(TopAbs_REVERSED);
400 // 2.3. Collect images Faces
401 myImagesFaces.Bind(aF, aLFR);
402 }//for (i=1; i<=aNbF; ++i)
404 //=======================================================================
405 // function: FillIn2DParts
407 //=======================================================================
408 void NMTAlgo_Builder::FillIn2DParts()
410 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
411 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
412 BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
413 BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
415 Standard_Integer i, j, aNb, nF1, nF2, aNbFF, iFF, nSpIn, nSpSc, aNbCurves;
416 BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap;
417 BOPTools_ListOfPaveBlock aLPBIn, aLPBSc;
418 BOPTools_ListIteratorOfListOfPaveBlock aItPBIn, aItPBSc;
419 TopTools_IndexedMapOfShape aMF, aMFence;
420 TopTools_ListOfShape aLSpIn, aLSpSc;
422 BOP_BuilderTools::DoMap(aFFs, aFFMap);
424 // 1. Collect Splits In 2D (myIn2DParts) and
425 // Section Edges (mySectionParts)
426 // for each source face that involved in FF
428 for (i=1; i<=aNb; ++i) {
429 nF1=aFFMap.FindKey(i);
430 const TopoDS_Shape& aF=aDS.Shape(nF1);
432 if (aMF.Contains(aF)) {
440 const TColStd_IndexedMapOfInteger& aFFIndicesMap=aFFMap.FindFromIndex(i);
442 aNbFF=aFFIndicesMap.Extent();
443 for (j=1; j<=aNbFF; ++j) {
444 iFF=aFFIndicesMap(j);
445 BOPTools_SSInterference& aFF=aFFs(iFF);
446 nF2=aFF.OppositeIndex(nF1);
449 pPF->RealSplitsInFace(0, nF2, nF1, aLPBIn);
452 BOPTools_SequenceOfCurves& aSC=aFF.Curves();
453 aNbCurves=aSC.Length();
458 const BOPTools_Curve& aBC=aSC(1);
459 const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
461 aItPBSc.Initialize(aLPB);
462 for (; aItPBSc.More(); aItPBSc.Next()) {
463 const BOPTools_PaveBlock& aPBSc=aItPBSc.Value();
464 aLPBSc.Append(aPBSc);
466 }// for (j=1; j<=aNbFF; ++j)
472 aItPBIn.Initialize(aLPBIn);
473 for (; aItPBIn.More(); aItPBIn.Next()) {
474 const BOPTools_PaveBlock& aPBR=aItPBIn.Value();
476 const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
477 if (!aMFence.Contains(aSpIn)){
479 aLSpIn.Append(aSpIn);
482 myIn2DParts.Add(aF, aLSpIn);
486 aItPBSc.Initialize(aLPBSc);
487 for (; aItPBSc.More(); aItPBSc.Next()) {
488 const BOPTools_PaveBlock& aPBSc=aItPBSc.Value();
490 const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
491 if (!aMFence.Contains(aSpSc)){
493 aLSpSc.Append(aSpSc);
496 mySectionParts.Add(aF, aLSpSc);
497 } //for (i=1; i<=aNb; ++i)
500 //=======================================================================
501 // function: FillImagesEdges
503 //=======================================================================
504 void NMTAlgo_Builder::FillImagesEdges()
506 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
507 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
508 const BOPTools_SplitShapesPool& aSSP=pPF->SplitShapesPool();
510 Standard_Integer nE, aNb, aNbSp, nSp;
511 BOPTools_ListIteratorOfListOfPaveBlock aIt;
512 TopTools_IndexedMapOfShape aMFence;
513 TopTools_ListOfShape aLSp;
515 aNb=aDS.NumberOfShapesOfTheObject();
516 for (nE=1; nE<=aNb; ++nE) {
517 const TopoDS_Shape& aE=aDS.Shape(nE);
518 if (aE.ShapeType()!=TopAbs_EDGE) {
521 if (aMFence.Contains(aE)) {
526 const BOPTools_ListOfPaveBlock& aLPB=aSSP(aDS.RefEdge(nE));
529 if (!aNbSp) {// no splits
530 //myImagesEdges.Bind(aE, aE);
534 //modified by NIZNHY-PKV Fri Jan 21 17:01:10 2005 f
536 const BOPTools_PaveBlock& aPB1=aLPB.First();
537 const BOPTools_PaveBlock& aPBR1=pPF->RealPaveBlock(aPB1);
539 const TopoDS_Shape& aSp1=aDS.Shape(nSp);
540 if (aSp1.IsSame(aE)) {
544 //modified by NIZNHY-PKV Fri Jan 21 17:01:14 2005 t
547 aIt.Initialize(aLPB);
548 for (; aIt.More(); aIt.Next()) {
549 const BOPTools_PaveBlock& aPB=aIt.Value();
550 const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB);
552 const TopoDS_Shape& aSp=aDS.Shape(nSp);
555 myImagesEdges.Bind(aE, aLSp);
558 //=======================================================================
559 // function: SplitVertices
561 //=======================================================================
562 void NMTAlgo_Builder::SplitVertices()
564 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
565 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
566 const BOPTools_SplitShapesPool& aSSP=pPF->SplitShapesPool();
568 Standard_Integer nE, aNb, aNbSp, nV1, nV2;
569 BOPTools_ListIteratorOfListOfPaveBlock aIt;
571 myQueryShapes.Clear();
573 aNb=aDS.NumberOfShapesOfTheObject();
574 for (nE=1; nE<=aNb; ++nE) {
575 const TopoDS_Shape& aE=aDS.Shape(nE);
576 if (aE.ShapeType()!=TopAbs_EDGE) {
580 const BOPTools_ListOfPaveBlock& aLPB=aSSP(aDS.RefEdge(nE));
583 if (!aNbSp) {// no splits
587 aIt.Initialize(aLPB);
588 for (; aIt.More(); aIt.Next()) {
589 const BOPTools_PaveBlock& aPB=aIt.Value();
590 const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB);
592 nV1=aPBR.Pave1().Index();
593 if (aDS.IsNewShape(nV1)) {
594 const TopoDS_Shape& aV1=aDS.Shape(nV1);
595 myQueryShapes.Add(aV1);
598 nV2=aPBR.Pave2().Index();
599 if (aDS.IsNewShape(nV2)) {
600 const TopoDS_Shape& aV2=aDS.Shape(nV2);
601 myQueryShapes.Add(aV2);
606 //=======================================================================
607 // function: IsSectionEdge
609 //=======================================================================
610 Standard_Boolean NMTAlgo_Builder::IsSectionEdge(const TopoDS_Edge& aE)const
612 return myImagesEdges.HasImage(aE);
614 //=======================================================================
615 // function: IsSameDomainF
617 //=======================================================================
618 Standard_Boolean NMTAlgo_Builder::HasSameDomainF(const TopoDS_Face& aF1)const
620 Standard_Boolean bFlag=Standard_False;
621 TopTools_ListIteratorOfListOfShape aItF1;
623 const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
624 aItF1.Initialize(aLF1);
625 for (; aItF1.More(); aItF1.Next()) {
626 const TopoDS_Shape& aF1x=aItF1.Value();
628 if (mySDFaces.Contains(aF1x)){
634 //=======================================================================
635 // function: IsSameDomainF
637 //=======================================================================
638 Standard_Boolean NMTAlgo_Builder::IsSameDomainF(const TopoDS_Face& aF1,
639 const TopoDS_Face& aF2)const
641 Standard_Boolean bFlag=Standard_False;
642 TopTools_ListIteratorOfListOfShape aItF1, aItF2;
644 const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
645 const TopTools_ListOfShape& aLF2=myImagesFaces.Image(aF2);
647 aItF1.Initialize(aLF1);
648 for (; aItF1.More(); aItF1.Next()) {
649 const TopoDS_Shape& aF1x=aItF1.Value();
651 if (!mySDFaces.Contains(aF1x)){
654 const TopoDS_Shape& aFSD1x=mySDFaces.FindFromKey(aF1x);
656 aItF2.Initialize(aLF2);
657 for (; aItF2.More(); aItF2.Next()) {
658 const TopoDS_Shape& aF2y=aItF2.Value();
659 if (!mySDFaces.Contains(aF2y)){
662 const TopoDS_Shape& aFSD2y=mySDFaces.FindFromKey(aF2y);
663 if (aFSD1x.IsSame(aFSD2y)) {