1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: NMTAlgo_Inter3d.cxx
21 // Created: Tue Jan 27 15:14:13 2004
22 // Author: Peter KURNEV
26 #include <NMTAlgo_Builder.ixx>
28 #include <TColStd_IndexedMapOfInteger.hxx>
30 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Compound.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Shape.hxx>
37 #include <TopExp_Explorer.hxx>
39 #include <BRep_Builder.hxx>
40 #include <BRep_Tool.hxx>
42 #include <TopTools_IndexedMapOfShape.hxx>
43 #include <TopTools_ListOfShape.hxx>
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <BOPTColStd_Dump.hxx>
47 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
49 #include <IntTools_Context.hxx>
51 #include <BOPTools_Tools3D.hxx>
52 #include <BOPTools_CArray1OfSSInterference.hxx>
53 #include <BOPTools_InterferencePool.hxx>
54 #include <BOPTools_SSInterference.hxx>
55 #include <BOPTools_SequenceOfCurves.hxx>
56 #include <BOPTools_Curve.hxx>
57 #include <BOPTools_SequenceOfCurves.hxx>
58 #include <BOPTools_SplitShapesPool.hxx>
59 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
60 #include <BOPTools_ListOfPaveBlock.hxx>
61 #include <BOPTools_PaveBlock.hxx>
63 #include <BOP_WireEdgeSet.hxx>
64 #include <BOP_FaceBuilder.hxx>
65 #include <BOP_BuilderTools.hxx>
67 #include <NMTDS_ShapesDataStructure.hxx>
69 #include <NMTTools_PaveFiller.hxx>
70 #include <NMTTools_ListOfCoupleOfShape.hxx>
71 #include <NMTTools_Tools.hxx>
72 #include <NMTTools_CoupleOfShape.hxx>
73 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
74 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
76 #include <TopoDS_Shell.hxx>
77 #include <NMTAlgo_Tools.hxx>
78 #include <TColStd_IndexedMapOfInteger.hxx>
79 #include <TopExp_Explorer.hxx>
80 #include <TopoDS_Iterator.hxx>
82 //=======================================================================
83 // function: NMTAlgo_Inter3d::NMTAlgo_Inter3d()
85 //=======================================================================
86 NMTAlgo_Builder::NMTAlgo_Builder()
91 //=======================================================================
92 // function: ~NMTAlgo_Builder
94 //=======================================================================
95 NMTAlgo_Builder::~NMTAlgo_Builder()
99 //=======================================================================
102 //=======================================================================
103 void NMTAlgo_Builder::Clear()
105 NMTAlgo_Algo::Clear();
107 myImagesEdges.Clear();
108 myImagesFaces.Clear();
110 mySectionParts.Clear();
113 //=======================================================================
114 // function: ComputeWithFiller
116 //=======================================================================
117 void NMTAlgo_Builder::ComputeWithFiller(const NMTTools_DSFiller& aDSF)
120 myIsDone=Standard_False;
131 //=======================================================================
132 // function: FillSDFaces
134 //=======================================================================
135 void NMTAlgo_Builder::FillSDFaces()
137 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
138 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
139 BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
140 BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
141 IntTools_Context& aCtx= pPF->ChangeContext();
143 Standard_Boolean bIsSDF;
144 Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC;
145 TopTools_ListIteratorOfListOfShape aItF1, aItF2;
146 NMTTools_ListOfCoupleOfShape aLCS;
150 // 1. For each FF find among images of faces
151 // all pairs of same domain faces (SDF) [=> aLCS]
153 for (i=1; i<=aNbFF; ++i) {
154 BOPTools_SSInterference& aFF=aFFs(i);
155 aFF.Indices(nF1, nF2);
157 const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
158 const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
160 // if there are no in/on 2D split parts the faces nF1, nF2
162 const BOPTools_ListOfPaveBlock& aLPBInOn=aFF.PaveBlocks();
163 aNbPBInOn=aLPBInOn.Extent();
168 // if there is at least one section edge between faces nF1, nF2
169 // they can not be SDF
170 BOPTools_SequenceOfCurves& aSC=aFF.Curves();
176 // the faces are suspected to be SDF.
177 // Try to find SDF among images of nF1, nF2
178 const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
179 const TopTools_ListOfShape& aLF2=myImagesFaces.Image(aF2);
181 aItF1.Initialize(aLF1);
182 for (; aItF1.More(); aItF1.Next()) {
183 const TopoDS_Face& aF1x=TopoDS::Face(aItF1.Value());
185 aItF2.Initialize(aLF2);
186 for (; aItF2.More(); aItF2.Next()) {
187 const TopoDS_Face& aF2y=TopoDS::Face(aItF2.Value());
188 bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx);
190 NMTTools_CoupleOfShape aCS;
198 }//for (i=1; i<=aNbFF; ++i)
206 NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;
208 NMTTools_Tools::FindChains(aLCS, aMC);
210 // 3. Fill the map of SDF mySDFaces
212 for (i=1; i<=aNbC; ++i) {
213 const TopoDS_Shape& aF=aMC.FindKey(i);
214 const TopTools_IndexedMapOfShape& aMSDF=aMC(i);
216 aNbFF=aMSDF.Extent();
217 for (j=1; j<=aNbFF; ++j) {
218 const TopoDS_Shape& aFSD=aMSDF(j);
219 mySDFaces.Add(aFSD, aF);
224 //=======================================================================
225 // function: FillImagesFaces
227 //=======================================================================
228 void NMTAlgo_Builder::FillImagesFaces()
230 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
231 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
232 IntTools_Context& aCtx= pPF->ChangeContext();
234 Standard_Integer i, j, aNb, aNbE;
235 TopTools_IndexedMapOfShape aMFence, aME;
236 TColStd_IndexedMapOfInteger aMFP;
238 // 1. Select Faces to process (MFP)
239 aNb=aDS.NumberOfShapesOfTheObject();
240 for (i=1; i<=aNb; ++i) {
241 const TopoDS_Shape& aF=aDS.Shape(i);
242 if (aF.ShapeType()!=TopAbs_FACE) {
245 if (aMFence.Contains(aF)) {
250 if (myIn2DParts.Contains(aF)) {
255 if (mySectionParts.Contains(aF)) {
261 TopExp::MapShapes(aF, TopAbs_EDGE, aME);
264 for(j=1; j<=aNbE; ++j) {
265 const TopoDS_Shape& aE=aME(j);
267 if (myImagesEdges.HasImage(aE)) {
272 }// for (i=1; i<=aNb; ++i)
275 Standard_Boolean bToReverse, bIsClosed, bIsDegenerated;
276 Standard_Integer aNbF, nF;
279 TopExp_Explorer anExp;
280 TopTools_ListIteratorOfListOfShape aIt;
281 BRepAlgo_Image aImagesFaces;
282 TopAbs_Orientation anOriF;
285 for (i=1; i<=aNbF; ++i) {
287 const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF));
288 anOriF=aF.Orientation();
290 aFF.Orientation(TopAbs_FORWARD);
295 BOP_WireEdgeSet aWES;
296 aWES.Initialize(aFF);
298 // 2.1.1. Add Split parts
299 anExp.Init(aFF, TopAbs_EDGE);
300 for (; anExp.More(); anExp.Next()) {
301 const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
303 if (!myImagesEdges.HasImage(aE)) {
304 aWES.AddStartElement(aE);
308 bIsDegenerated=BRep_Tool::Degenerated(aE);
309 bIsClosed=BRep_Tool::IsClosed(aE, aF);
311 const TopTools_ListOfShape& aLIE=myImagesEdges.Image(aE);
312 aIt.Initialize(aLIE);
313 for (; aIt.More(); aIt.Next()) {
314 aSp=TopoDS::Edge(aIt.Value());
316 if (bIsDegenerated) {
317 aSp.Orientation(aE.Orientation());
318 aWES.AddStartElement(aSp);
323 if (!aMFence.Contains(aSp)){
326 if (!BRep_Tool::IsClosed(aSp, aF)){
327 BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
330 aSp.Orientation(TopAbs_FORWARD);
331 aWES.AddStartElement(aSp);
333 aSp.Orientation(TopAbs_REVERSED);
334 aWES.AddStartElement(aSp);
339 bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
343 aWES.AddStartElement(aSp);
347 // 2.1.2. Add In2D Parts
348 if (myIn2DParts.Contains(aF)) {
349 const TopTools_ListOfShape& aLE=myIn2DParts.FindFromKey(aF);
351 for (; aIt.More(); aIt.Next()) {
352 aSp=TopoDS::Edge(aIt.Value());
354 aSp.Orientation(TopAbs_FORWARD);
355 aWES.AddStartElement(aSp);
357 aSp.Orientation(TopAbs_REVERSED);
358 aWES.AddStartElement(aSp);
362 // 2.1.3. Add Section Parts
363 if (mySectionParts.Contains(aF)) {
364 const TopTools_ListOfShape& aLE=mySectionParts.FindFromKey(aF);
366 for (; aIt.More(); aIt.Next()) {
367 aSp=TopoDS::Edge(aIt.Value());
369 aSp.Orientation(TopAbs_FORWARD);
370 aWES.AddStartElement(aSp);
372 aSp.Orientation(TopAbs_REVERSED);
373 aWES.AddStartElement(aSp);
377 // 2.2. Build images Faces
380 aFB.SetTreatment(0); // 0-Do Internal Edges
381 aFB.SetTreatSDScales(0); // what is 0 ??
385 TopTools_ListOfShape aLFR;
387 const TopTools_ListOfShape& aLF=aFB.NewFaces();
390 for (; aIt.More(); aIt.Next()) {
391 TopoDS_Shape& aFR=aIt.Value();
392 if (anOriF==TopAbs_REVERSED) {
393 aFR.Orientation(TopAbs_REVERSED);
399 // 2.3. Collect images Faces
400 myImagesFaces.Bind(aF, aLFR);
401 }//for (i=1; i<=aNbF; ++i)
403 //=======================================================================
404 // function: FillIn2DParts
406 //=======================================================================
407 void NMTAlgo_Builder::FillIn2DParts()
409 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
410 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
411 BOPTools_InterferencePool* pIP=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
412 BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
414 Standard_Integer i, j, aNb, nF1, nF2, aNbFF, iFF, nSpIn, nSpSc, aNbCurves;
415 BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap;
416 BOPTools_ListOfPaveBlock aLPBIn, aLPBSc;
417 BOPTools_ListIteratorOfListOfPaveBlock aItPBIn, aItPBSc;
418 TopTools_IndexedMapOfShape aMF, aMFence;
419 TopTools_ListOfShape aLSpIn, aLSpSc;
421 BOP_BuilderTools::DoMap(aFFs, aFFMap);
423 // 1. Collect Splits In 2D (myIn2DParts) and
424 // Section Edges (mySectionParts)
425 // for each source face that involved in FF
427 for (i=1; i<=aNb; ++i) {
428 nF1=aFFMap.FindKey(i);
429 const TopoDS_Shape& aF=aDS.Shape(nF1);
431 if (aMF.Contains(aF)) {
439 const TColStd_IndexedMapOfInteger& aFFIndicesMap=aFFMap.FindFromIndex(i);
441 aNbFF=aFFIndicesMap.Extent();
442 for (j=1; j<=aNbFF; ++j) {
443 iFF=aFFIndicesMap(j);
444 BOPTools_SSInterference& aFF=aFFs(iFF);
445 nF2=aFF.OppositeIndex(nF1);
448 pPF->RealSplitsInFace(0, nF2, nF1, aLPBIn);
451 BOPTools_SequenceOfCurves& aSC=aFF.Curves();
452 aNbCurves=aSC.Length();
457 const BOPTools_Curve& aBC=aSC(1);
458 const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
460 aItPBSc.Initialize(aLPB);
461 for (; aItPBSc.More(); aItPBSc.Next()) {
462 const BOPTools_PaveBlock& aPBSc=aItPBSc.Value();
463 aLPBSc.Append(aPBSc);
465 }// for (j=1; j<=aNbFF; ++j)
471 aItPBIn.Initialize(aLPBIn);
472 for (; aItPBIn.More(); aItPBIn.Next()) {
473 const BOPTools_PaveBlock& aPBR=aItPBIn.Value();
475 const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
476 if (!aMFence.Contains(aSpIn)){
478 aLSpIn.Append(aSpIn);
481 myIn2DParts.Add(aF, aLSpIn);
485 aItPBSc.Initialize(aLPBSc);
486 for (; aItPBSc.More(); aItPBSc.Next()) {
487 const BOPTools_PaveBlock& aPBSc=aItPBSc.Value();
489 const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
490 if (!aMFence.Contains(aSpSc)){
492 aLSpSc.Append(aSpSc);
495 mySectionParts.Add(aF, aLSpSc);
496 } //for (i=1; i<=aNb; ++i)
499 //=======================================================================
500 // function: FillImagesEdges
502 //=======================================================================
503 void NMTAlgo_Builder::FillImagesEdges()
505 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
506 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
507 const BOPTools_SplitShapesPool& aSSP=pPF->SplitShapesPool();
509 Standard_Integer nE, aNb, aNbSp, nSp;
510 BOPTools_ListIteratorOfListOfPaveBlock aIt;
511 TopTools_IndexedMapOfShape aMFence;
512 TopTools_ListOfShape aLSp;
514 aNb=aDS.NumberOfShapesOfTheObject();
515 for (nE=1; nE<=aNb; ++nE) {
516 const TopoDS_Shape& aE=aDS.Shape(nE);
517 if (aE.ShapeType()!=TopAbs_EDGE) {
520 if (aMFence.Contains(aE)) {
525 const BOPTools_ListOfPaveBlock& aLPB=aSSP(aDS.RefEdge(nE));
528 if (!aNbSp) {// no splits
529 //myImagesEdges.Bind(aE, aE);
533 //modified by NIZNHY-PKV Fri Jan 21 17:01:10 2005 f
535 const BOPTools_PaveBlock& aPB1=aLPB.First();
536 const BOPTools_PaveBlock& aPBR1=pPF->RealPaveBlock(aPB1);
538 const TopoDS_Shape& aSp1=aDS.Shape(nSp);
539 if (aSp1.IsSame(aE)) {
543 //modified by NIZNHY-PKV Fri Jan 21 17:01:14 2005 t
546 aIt.Initialize(aLPB);
547 for (; aIt.More(); aIt.Next()) {
548 const BOPTools_PaveBlock& aPB=aIt.Value();
549 const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB);
551 const TopoDS_Shape& aSp=aDS.Shape(nSp);
554 myImagesEdges.Bind(aE, aLSp);
557 //=======================================================================
558 // function: SplitVertices
560 //=======================================================================
561 void NMTAlgo_Builder::SplitVertices()
563 const NMTDS_ShapesDataStructure& aDS=myDSFiller->DS();
564 NMTTools_PaveFiller* pPF=(NMTTools_PaveFiller*)&(myDSFiller->PaveFiller());
565 const BOPTools_SplitShapesPool& aSSP=pPF->SplitShapesPool();
567 Standard_Integer nE, aNb, aNbSp, nV1, nV2;
568 BOPTools_ListIteratorOfListOfPaveBlock aIt;
570 myQueryShapes.Clear();
572 aNb=aDS.NumberOfShapesOfTheObject();
573 for (nE=1; nE<=aNb; ++nE) {
574 const TopoDS_Shape& aE=aDS.Shape(nE);
575 if (aE.ShapeType()!=TopAbs_EDGE) {
579 const BOPTools_ListOfPaveBlock& aLPB=aSSP(aDS.RefEdge(nE));
582 if (!aNbSp) {// no splits
586 aIt.Initialize(aLPB);
587 for (; aIt.More(); aIt.Next()) {
588 const BOPTools_PaveBlock& aPB=aIt.Value();
589 const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB);
591 nV1=aPBR.Pave1().Index();
592 if (aDS.IsNewShape(nV1)) {
593 const TopoDS_Shape& aV1=aDS.Shape(nV1);
594 myQueryShapes.Add(aV1);
597 nV2=aPBR.Pave2().Index();
598 if (aDS.IsNewShape(nV2)) {
599 const TopoDS_Shape& aV2=aDS.Shape(nV2);
600 myQueryShapes.Add(aV2);
605 //=======================================================================
606 // function: IsSectionEdge
608 //=======================================================================
609 Standard_Boolean NMTAlgo_Builder::IsSectionEdge(const TopoDS_Edge& aE)const
611 return myImagesEdges.HasImage(aE);
613 //=======================================================================
614 // function: IsSameDomainF
616 //=======================================================================
617 Standard_Boolean NMTAlgo_Builder::HasSameDomainF(const TopoDS_Face& aF1)const
619 Standard_Boolean bFlag=Standard_False;
620 TopTools_ListIteratorOfListOfShape aItF1;
622 const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
623 aItF1.Initialize(aLF1);
624 for (; aItF1.More(); aItF1.Next()) {
625 const TopoDS_Shape& aF1x=aItF1.Value();
627 if (mySDFaces.Contains(aF1x)){
633 //=======================================================================
634 // function: IsSameDomainF
636 //=======================================================================
637 Standard_Boolean NMTAlgo_Builder::IsSameDomainF(const TopoDS_Face& aF1,
638 const TopoDS_Face& aF2)const
640 Standard_Boolean bFlag=Standard_False;
641 TopTools_ListIteratorOfListOfShape aItF1, aItF2;
643 const TopTools_ListOfShape& aLF1=myImagesFaces.Image(aF1);
644 const TopTools_ListOfShape& aLF2=myImagesFaces.Image(aF2);
646 aItF1.Initialize(aLF1);
647 for (; aItF1.More(); aItF1.Next()) {
648 const TopoDS_Shape& aF1x=aItF1.Value();
650 if (!mySDFaces.Contains(aF1x)){
653 const TopoDS_Shape& aFSD1x=mySDFaces.FindFromKey(aF1x);
655 aItF2.Initialize(aLF2);
656 for (; aItF2.More(); aItF2.Next()) {
657 const TopoDS_Shape& aF2y=aItF2.Value();
658 if (!mySDFaces.Contains(aF2y)){
661 const TopoDS_Shape& aFSD2y=mySDFaces.FindFromKey(aF2y);
662 if (aFSD1x.IsSame(aFSD2y)) {