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
6 //
7 // This file is part of Open CASCADE Technology software library.
8 //
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.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17 
18 
19 #include <Bnd_Box.hxx>
20 #include <BOPAlgo_PaveFiller.hxx>
21 #include <BOPAlgo_Tools.hxx>
22 #include <BOPAlgo_Alerts.hxx>
23 #include <BOPDS_DS.hxx>
24 #include <BOPDS_Iterator.hxx>
25 #include <BOPDS_PaveBlock.hxx>
26 #include <BOPDS_ShapeInfo.hxx>
27 #include <BOPDS_VectorOfInterfVV.hxx>
28 #include <BOPTools_AlgoTools.hxx>
29 #include <BRep_Builder.hxx>
30 #include <BRep_TVertex.hxx>
31 #include <BRep_Tool.hxx>
32 #include <gp_Pnt.hxx>
33 #include <IntTools_Context.hxx>
34 #include <NCollection_BaseAllocator.hxx>
35 #include <Precision.hxx>
36 #include <TColStd_DataMapOfIntegerInteger.hxx>
37 #include <TopoDS.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Vertex.hxx>
40 #include <TopoDS_Compound.hxx>
41 #include <TopTools_ListOfShape.hxx>
42 
43 //=======================================================================
44 // function: PerformVV
45 // purpose:
46 //=======================================================================
PerformVV(const Message_ProgressRange & theRange)47 void BOPAlgo_PaveFiller::PerformVV(const Message_ProgressRange& theRange)
48 {
49   Standard_Integer n1, n2, iFlag, aSize;
50   Handle(NCollection_BaseAllocator) aAllocator;
51   //
52   myIterator->Initialize(TopAbs_VERTEX, TopAbs_VERTEX);
53   aSize=myIterator->ExpectedLength();
54   Message_ProgressScope aPS(theRange, NULL, 2.);
55   if (!aSize) {
56     return;
57   }
58   //
59   BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
60   aVVs.SetIncrement(aSize);
61   //
62   //-----------------------------------------------------scope f
63   aAllocator=
64     NCollection_BaseAllocator::CommonBaseAllocator();
65   NCollection_IndexedDataMap<Standard_Integer, TColStd_ListOfInteger>aMILI(100, aAllocator);
66   NCollection_List<TColStd_ListOfInteger> aMBlocks(aAllocator);
67   //
68   // 1. Map V/LV
69   // Split progress range on intersection stage and making blocks. Display only intersection stage.
70   Message_ProgressScope aPSLoop(aPS.Next(1.), "Performing Vertex-Vertex intersection", aSize);
71   for (; myIterator->More(); myIterator->Next(), aPSLoop.Next()) {
72     if (UserBreak(aPS))
73     {
74       return;
75     }
76     myIterator->Value(n1, n2);
77     //
78     if (myDS->HasInterf(n1, n2))
79     {
80       BOPAlgo_Tools::FillMap<Standard_Integer, TColStd_MapIntegerHasher>(n1, n2, aMILI, aAllocator);
81       continue;
82     }
83 
84     // Check for SD vertices
85     Standard_Integer n1SD = n1;
86     myDS->HasShapeSD(n1, n1SD);
87 
88     Standard_Integer n2SD = n2;
89     myDS->HasShapeSD(n2, n2SD);
90 
91     const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(n1SD)));
92     const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(n2SD)));
93 
94     iFlag = BOPTools_AlgoTools::ComputeVV(aV1, aV2, myFuzzyValue);
95     if (!iFlag) {
96       BOPAlgo_Tools::FillMap<Standard_Integer, TColStd_MapIntegerHasher>(n1, n2, aMILI, aAllocator);
97     }
98   }
99   //
100   // 2. Make blocks
101   BOPAlgo_Tools::MakeBlocks<Standard_Integer, TColStd_MapIntegerHasher>(aMILI, aMBlocks, aAllocator);
102   //
103   // 3. Make vertices
104   NCollection_List<TColStd_ListOfInteger>::Iterator aItB(aMBlocks);
105   for (; aItB.More(); aItB.Next()) {
106     if (UserBreak(aPS))
107     {
108       return;
109     }
110     const TColStd_ListOfInteger& aLI = aItB.Value();
111     MakeSDVertices(aLI);
112   }
113   //
114   TColStd_DataMapIteratorOfDataMapOfIntegerInteger aItDMII;
115   //
116   TColStd_DataMapOfIntegerInteger& aDMII=myDS->ShapesSD();
117   aItDMII.Initialize(aDMII);
118   for (; aItDMII.More(); aItDMII.Next()) {
119     if (UserBreak(aPS))
120     {
121       return;
122     }
123     n1=aItDMII.Key();
124     myDS->InitPaveBlocksForVertex(n1);
125   }
126   //
127   //-----------------------------------------------------scope t
128   aMBlocks.Clear();
129   aMILI.Clear();
130 }
131 
132 //=======================================================================
133 // function: MakeSDVertices
134 // purpose:
135 //=======================================================================
MakeSDVertices(const TColStd_ListOfInteger & theVertIndices,const Standard_Boolean theAddInterfs)136 Standard_Integer BOPAlgo_PaveFiller::MakeSDVertices
137    (const TColStd_ListOfInteger& theVertIndices,
138     const Standard_Boolean theAddInterfs)
139 {
140   TopoDS_Vertex aVSD, aVn;
141   Standard_Integer nSD = -1;
142   TColStd_ListIteratorOfListOfInteger aItLI(theVertIndices);
143   TopTools_ListOfShape aLV;
144   for (; aItLI.More(); aItLI.Next()) {
145     Standard_Integer nX = aItLI.Value(), nSD1;
146     if (myDS->HasShapeSD(nX, nSD1)) {
147       const TopoDS_Shape& aVSD1 = myDS->Shape(nSD1);
148       if (nSD == -1) {
149         aVSD = TopoDS::Vertex(aVSD1);
150         nSD = nSD1;
151       }
152       else {
153         aLV.Append(aVSD1);
154       }
155     }
156     const TopoDS_Shape& aV = myDS->Shape(nX);
157     aLV.Append(aV);
158   }
159   BOPTools_AlgoTools::MakeVertex(aLV, aVn);
160   Standard_Integer nV;
161   if (nSD != -1) {
162     // update old SD vertex with new value
163     BRep_TVertex* aTVertex = static_cast<BRep_TVertex*>(aVSD.TShape().get());
164     aTVertex->Pnt(BRep_Tool::Pnt(aVn));
165     aTVertex->Tolerance(BRep_Tool::Tolerance(aVn));
166     aVn = aVSD;
167     nV = nSD;
168   }
169   else {
170     // Append new vertex to the DS
171     BOPDS_ShapeInfo aSIn;
172     aSIn.SetShapeType(TopAbs_VERTEX);
173     aSIn.SetShape(aVn);
174     nV = myDS->Append(aSIn);
175   }
176   BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(nV);
177   Bnd_Box& aBox = aSIDS.ChangeBox();
178   aBox.Add(BRep_Tool::Pnt(aVn));
179   aBox.SetGap(BRep_Tool::Tolerance(aVn) + Precision::Confusion());
180   //
181   // Fill ShapesSD
182   BOPDS_VectorOfInterfVV& aVVs = myDS->InterfVV();
183   if (theAddInterfs)
184     aVVs.SetIncrement(theVertIndices.Extent());
185   //
186   aItLI.Initialize(theVertIndices);
187   for (; aItLI.More(); aItLI.Next()) {
188     Standard_Integer n1 = aItLI.Value();
189     myDS->AddShapeSD(n1, nV);
190     //
191     Standard_Integer iR1 = myDS->Rank(n1);
192     const TopoDS_Shape& aV1 = myDS->Shape(n1);
193     //
194     TColStd_ListIteratorOfListOfInteger aItLI2 = aItLI;
195     aItLI2.Next();
196     for (; aItLI2.More(); aItLI2.Next()) {
197       Standard_Integer n2 = aItLI2.Value();
198       //
199       if (iR1 >= 0 && iR1 == myDS->Rank(n2)) {
200         // add warning status
201         const TopoDS_Shape& aV2 = myDS->Shape(n2);
202         //
203         TopoDS_Compound aWC;
204         BRep_Builder().MakeCompound(aWC);
205         BRep_Builder().Add(aWC, aV1);
206         BRep_Builder().Add(aWC, aV2);
207         //
208         AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
209       }
210       //
211       if (theAddInterfs) {
212         if (myDS->AddInterf(n1, n2))
213         {
214           BOPDS_InterfVV& aVV = aVVs.Appended();
215           aVV.SetIndices(n1, n2);
216           aVV.SetIndexNew(nV);
217         }
218       }
219     }
220   }
221   return nV;
222 }
223