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