b311480e |
1 | // Created on: 1995-09-08 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
7fd59977 |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
7fd59977 |
17 | // modified by mps (juillet 96) : ajout de la commande distmini |
18 | |
19 | #include <DBRep.hxx> |
20 | #include <BRepTest.hxx> |
7fd59977 |
21 | #include <BRepExtrema_Poly.hxx> |
22 | #include <BRepExtrema_DistShapeShape.hxx> |
558e68ea |
23 | #include <BRepExtrema_ShapeProximity.hxx> |
ae9a414a |
24 | #include <BRepExtrema_SelfIntersection.hxx> |
7fd59977 |
25 | #include <BRepLib_MakeEdge.hxx> |
7fd59977 |
26 | #include <BRepLib_MakeVertex.hxx> |
ae9a414a |
27 | #include <BRepBuilderAPI_MakeEdge.hxx> |
558e68ea |
28 | #include <TopoDS_Builder.hxx> |
29 | #include <TopoDS_Compound.hxx> |
7fd59977 |
30 | #include <Draw.hxx> |
558e68ea |
31 | #include <OSD_Timer.hxx> |
32 | #include <TCollection_AsciiString.hxx> |
33 | #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx> |
f84bf635 |
34 | #include <Precision.hxx> |
558e68ea |
35 | |
762b6cec |
36 | |
57c28b61 |
37 | //#ifdef _MSC_VER |
7fd59977 |
38 | #include <stdio.h> |
39 | //#endif |
40 | |
41 | //======================================================================= |
42 | //function : distance |
43 | //purpose : |
44 | //======================================================================= |
45 | |
46 | static Standard_Integer distance (Draw_Interpretor& di, |
47 | Standard_Integer n, |
48 | const char** a) |
49 | { |
50 | if (n < 3) return 1; |
51 | |
52 | const char *name1 = a[1]; |
53 | const char *name2 = a[2]; |
54 | |
55 | TopoDS_Shape S1 = DBRep::Get(name1); |
56 | TopoDS_Shape S2 = DBRep::Get(name2); |
57 | if (S1.IsNull() || S2.IsNull()) return 1; |
58 | gp_Pnt P1,P2; |
59 | Standard_Real D; |
60 | if (!BRepExtrema_Poly::Distance(S1,S2,P1,P2,D)) return 1; |
61 | //cout << " distance : " << D << endl; |
62 | di << " distance : " << D << "\n"; |
63 | TopoDS_Edge E = BRepLib_MakeEdge(P1,P2); |
64 | DBRep::Set("distance",E); |
65 | return 0; |
66 | } |
762b6cec |
67 | |
7fd59977 |
68 | static Standard_Integer distmini(Draw_Interpretor& di, Standard_Integer n, const char** a) |
f84bf635 |
69 | { |
70 | if (n != 4 && n != 5 ) |
71 | return 1; |
7fd59977 |
72 | |
73 | const char *ns1 = (a[2]), *ns2 = (a[3]), *ns0 = (a[1]); |
f84bf635 |
74 | TopoDS_Shape S1(DBRep::Get(ns1)), S2(DBRep::Get(ns2)); |
75 | |
76 | Standard_Real aDeflection = Precision::Confusion(); |
77 | if (n == 5) |
f79b19a1 |
78 | aDeflection = Draw::Atof(a[4]); |
7fd59977 |
79 | |
f84bf635 |
80 | BRepExtrema_DistShapeShape dst(S1 ,S2, aDeflection); |
7fd59977 |
81 | |
82 | if (dst.IsDone()) |
9e20ed57 |
83 | { |
0797d9d3 |
84 | #ifdef OCCT_DEBUG |
9e20ed57 |
85 | //dst.Dump(cout); |
86 | di << "*** Dump of \"BRepExtrema_DistShapeShape\" in DEBUG mode (begin) *****\n"; |
87 | Standard_SStream aSStream; |
88 | dst.Dump(aSStream); |
89 | di << aSStream; |
90 | di << "*** Dump of \"BRepExtrema_DistShapeShape\" in DEBUG mode (end) *****\n"; |
7fd59977 |
91 | #endif |
92 | |
9e20ed57 |
93 | di << "\"distmini\" command returns:\n"; |
94 | |
95 | char named[100]; |
96 | Sprintf(named, "%s%s" ,ns0,"_val"); |
97 | char* tempd = named; |
98 | Draw::Set(tempd,dst.Value()); |
99 | di << named << " "; |
100 | |
f84bf635 |
101 | for (Standard_Integer i1 = 1; i1<= dst.NbSolution(); i1++) |
9e20ed57 |
102 | { |
103 | gp_Pnt P1,P2; |
104 | P1 = (dst.PointOnShape1(i1)); |
105 | P2 = (dst.PointOnShape2(i1)); |
106 | if (dst.Value()<=1.e-9) |
107 | { |
108 | TopoDS_Vertex V =BRepLib_MakeVertex(P1); |
109 | char namev[100]; |
110 | if (i1==1) |
111 | Sprintf(namev, "%s" ,ns0); |
112 | else |
113 | Sprintf(namev, "%s%d" ,ns0,i1); |
114 | char* tempv = namev; |
115 | DBRep::Set(tempv,V); |
116 | di << namev << " "; |
7fd59977 |
117 | } |
9e20ed57 |
118 | else |
119 | { |
120 | char name[100]; |
121 | TopoDS_Edge E = BRepLib_MakeEdge (P1, P2); |
122 | if (i1==1) |
123 | { |
124 | Sprintf(name,"%s",ns0); |
125 | } |
126 | else |
127 | { |
128 | Sprintf(name,"%s%d",ns0,i1); |
129 | } |
130 | |
131 | char* temp = name; |
132 | DBRep::Set(temp,E); |
133 | di << name << " " ; |
134 | } |
135 | } |
136 | |
137 | di << "\nOutput is complete.\n"; |
138 | |
139 | } |
7fd59977 |
140 | |
c894a5fd |
141 | else di << "problem: no distance is found\n"; |
7fd59977 |
142 | return 0; |
143 | } |
144 | |
558e68ea |
145 | //============================================================================== |
146 | //function : ShapeProximity |
147 | //purpose : |
148 | //============================================================================== |
149 | static int ShapeProximity (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgs) |
150 | { |
151 | if (theNbArgs < 3 || theNbArgs > 6) |
152 | { |
153 | std::cout << "Usage: " << theArgs[0] << |
154 | " Shape1 Shape2 [-tol <value>] [-profile]" << std::endl; |
155 | |
156 | return 1; |
157 | } |
158 | |
159 | TopoDS_Shape aShape1 = DBRep::Get (theArgs[1]); |
160 | TopoDS_Shape aShape2 = DBRep::Get (theArgs[2]); |
161 | |
162 | if (aShape1.IsNull() || aShape2.IsNull()) |
163 | { |
164 | std::cout << "Error: Failed to find specified shapes" << std::endl; |
165 | return 1; |
166 | } |
167 | |
168 | BRepExtrema_ShapeProximity aTool; |
169 | |
170 | Standard_Boolean aProfile = Standard_False; |
171 | |
172 | for (Standard_Integer anArgIdx = 3; anArgIdx < theNbArgs; ++anArgIdx) |
173 | { |
174 | TCollection_AsciiString aFlag (theArgs[anArgIdx]); |
175 | aFlag.LowerCase(); |
176 | |
177 | if (aFlag == "-tol") |
178 | { |
179 | if (++anArgIdx >= theNbArgs) |
180 | { |
181 | std::cout << "Error: wrong syntax at argument '" << aFlag << std::endl; |
182 | return 1; |
183 | } |
184 | |
185 | const Standard_Real aTolerance = Draw::Atof (theArgs[anArgIdx]); |
186 | if (aTolerance < 0.0) |
187 | { |
188 | std::cout << "Error: Tolerance value should be non-negative" << std::endl; |
189 | return 1; |
190 | } |
191 | else |
192 | { |
193 | aTool.SetTolerance (aTolerance); |
194 | } |
195 | } |
196 | |
197 | if (aFlag == "-profile") |
198 | { |
199 | aProfile = Standard_True; |
200 | } |
201 | } |
202 | |
203 | Standard_Real aInitTime = 0.0; |
204 | Standard_Real aWorkTime = 0.0; |
205 | |
206 | OSD_Timer aTimer; |
207 | |
208 | if (aProfile) |
209 | { |
210 | aTimer.Start(); |
211 | } |
212 | |
213 | aTool.LoadShape1 (aShape1); |
214 | aTool.LoadShape2 (aShape2); |
215 | |
216 | if (aProfile) |
217 | { |
218 | aInitTime = aTimer.ElapsedTime(); |
219 | aTimer.Reset(); |
220 | aTimer.Start(); |
221 | } |
222 | |
223 | // Perform shape proximity test |
224 | aTool.Perform(); |
225 | |
226 | if (aProfile) |
227 | { |
228 | aWorkTime = aTimer.ElapsedTime(); |
229 | aTimer.Stop(); |
230 | } |
231 | |
232 | if (!aTool.IsDone()) |
233 | { |
234 | std::cout << "Error: Failed to perform proximity test" << std::endl; |
235 | return 1; |
236 | } |
237 | |
238 | if (aProfile) |
239 | { |
ae9a414a |
240 | theDI << "Number of primitives in shape 1: " << aTool.ElementSet1()->Size() << "\n"; |
241 | theDI << "Number of primitives in shape 2: " << aTool.ElementSet2()->Size() << "\n"; |
558e68ea |
242 | theDI << "Building data structures: " << aInitTime << "\n"; |
243 | theDI << "Executing proximity test: " << aWorkTime << "\n"; |
244 | } |
245 | |
ae9a414a |
246 | TopoDS_Builder aCompBuilder; |
558e68ea |
247 | |
248 | TopoDS_Compound aFaceCompound1; |
249 | aCompBuilder.MakeCompound (aFaceCompound1); |
250 | |
ae9a414a |
251 | for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt1 (aTool.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) |
558e68ea |
252 | { |
253 | TCollection_AsciiString aStr = TCollection_AsciiString (theArgs[1]) + "_" + (anIt1.Key() + 1); |
254 | |
255 | const TopoDS_Face& aFace = aTool.GetSubShape1 (anIt1.Key()); |
256 | aCompBuilder.Add (aFaceCompound1, aFace); |
257 | DBRep::Set (aStr.ToCString(), aFace); |
258 | |
259 | theDI << aStr << " \n"; |
260 | } |
261 | |
262 | TopoDS_Compound aFaceCompound2; |
263 | aCompBuilder.MakeCompound (aFaceCompound2); |
264 | |
ae9a414a |
265 | for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt2 (aTool.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) |
558e68ea |
266 | { |
267 | TCollection_AsciiString aStr = TCollection_AsciiString (theArgs[2]) + "_" + (anIt2.Key() + 1); |
268 | |
269 | const TopoDS_Face& aFace = aTool.GetSubShape2 (anIt2.Key()); |
270 | aCompBuilder.Add (aFaceCompound2, aFace); |
271 | DBRep::Set (aStr.ToCString(), aFace); |
272 | |
273 | theDI << aStr << " \n"; |
274 | } |
275 | |
276 | DBRep::Set ((TCollection_AsciiString (theArgs[1]) + "_" + "overlapped").ToCString(), aFaceCompound1); |
277 | DBRep::Set ((TCollection_AsciiString (theArgs[2]) + "_" + "overlapped").ToCString(), aFaceCompound2); |
278 | |
279 | return 0; |
280 | } |
281 | |
ae9a414a |
282 | //============================================================================== |
283 | //function : ShapeSelfIntersection |
284 | //purpose : |
285 | //============================================================================== |
286 | static int ShapeSelfIntersection (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgs) |
287 | { |
288 | if (theNbArgs < 2 || theNbArgs > 5) |
289 | { |
290 | std::cout << "Usage: " << theArgs[0] << |
291 | " Shape [-tol <value>] [-profile]" << std::endl; |
292 | |
293 | return 1; |
294 | } |
295 | |
296 | TopoDS_Shape aShape = DBRep::Get (theArgs[1]); |
297 | |
298 | if (aShape.IsNull()) |
299 | { |
300 | std::cout << "Error: Failed to find specified shape" << std::endl; |
301 | return 1; |
302 | } |
303 | |
304 | Standard_Real aTolerance = 0.0; |
305 | Standard_Boolean aToProfile = Standard_False; |
306 | |
307 | for (Standard_Integer anArgIdx = 2; anArgIdx < theNbArgs; ++anArgIdx) |
308 | { |
309 | TCollection_AsciiString aFlag (theArgs[anArgIdx]); |
310 | aFlag.LowerCase(); |
311 | |
312 | if (aFlag == "-tol") |
313 | { |
314 | if (++anArgIdx >= theNbArgs) |
315 | { |
316 | std::cout << "Error: wrong syntax at argument '" << aFlag << std::endl; |
317 | return 1; |
318 | } |
319 | |
320 | const Standard_Real aValue = Draw::Atof (theArgs[anArgIdx]); |
321 | if (aValue < 0.0) |
322 | { |
323 | std::cout << "Error: Tolerance value should be non-negative" << std::endl; |
324 | return 1; |
325 | } |
326 | else |
327 | { |
328 | aTolerance = aValue; |
329 | } |
330 | } |
331 | |
332 | if (aFlag == "-profile") |
333 | { |
334 | aToProfile = Standard_True; |
335 | } |
336 | } |
337 | |
338 | OSD_Timer aTimer; |
339 | |
340 | Standard_Real aInitTime = 0.0; |
341 | Standard_Real aWorkTime = 0.0; |
342 | |
343 | if (aToProfile) |
344 | { |
345 | aTimer.Start(); |
346 | } |
347 | |
348 | BRepExtrema_SelfIntersection aTool (aShape, aTolerance); |
349 | |
350 | if (aToProfile) |
351 | { |
352 | aInitTime = aTimer.ElapsedTime(); |
353 | |
354 | aTimer.Reset(); |
355 | aTimer.Start(); |
356 | } |
357 | |
358 | // Perform shape self-intersection test |
359 | aTool.Perform(); |
360 | |
361 | if (!aTool.IsDone()) |
362 | { |
363 | std::cout << "Error: Failed to perform proximity test" << std::endl; |
364 | return 1; |
365 | } |
366 | |
367 | if (aToProfile) |
368 | { |
369 | aWorkTime = aTimer.ElapsedTime(); |
370 | aTimer.Stop(); |
371 | |
372 | theDI << "Building data structure (BVH): " << aInitTime << "\n"; |
373 | theDI << "Executing self-intersection test: " << aWorkTime << "\n"; |
374 | } |
375 | |
376 | // Extract output faces |
377 | TopoDS_Builder aCompBuilder; |
378 | TopoDS_Compound aFaceCompound; |
379 | |
380 | aCompBuilder.MakeCompound (aFaceCompound); |
381 | |
382 | for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt (aTool.OverlapElements()); anIt.More(); anIt.Next()) |
383 | { |
384 | TCollection_AsciiString aStr = TCollection_AsciiString (theArgs[1]) + "_" + (anIt.Key() + 1); |
385 | |
386 | const TopoDS_Face& aFace = aTool.GetSubShape (anIt.Key()); |
387 | aCompBuilder.Add (aFaceCompound, aFace); |
388 | DBRep::Set (aStr.ToCString(), aFace); |
389 | |
390 | theDI << aStr << " \n"; |
391 | } |
392 | |
393 | theDI << "Compound of overlapped sub-faces: " << theArgs[1] << "_overlapped\n"; |
394 | DBRep::Set ((TCollection_AsciiString (theArgs[1]) + "_" + "overlapped").ToCString(), aFaceCompound); |
395 | |
396 | return 0; |
397 | } |
398 | |
7fd59977 |
399 | //======================================================================= |
400 | //function : ExtremaCommands |
401 | //purpose : |
402 | //======================================================================= |
403 | |
762b6cec |
404 | void BRepTest::ExtremaCommands (Draw_Interpretor& theCommands) |
7fd59977 |
405 | { |
762b6cec |
406 | static const char* aGroup = "TOPOLOGY Extrema commands"; |
407 | static Standard_Boolean isDone = Standard_False; |
408 | if (isDone) |
409 | { |
410 | return; |
411 | } |
412 | isDone = Standard_True; |
413 | |
414 | theCommands.Add ("dist", |
415 | "dist Shape1 Shape2", |
416 | __FILE__, |
417 | distance, |
418 | aGroup); |
419 | |
420 | theCommands.Add ("distmini", |
f84bf635 |
421 | "distmini name Shape1 Shape2 [deflection]", |
762b6cec |
422 | __FILE__, |
423 | distmini, |
424 | aGroup); |
558e68ea |
425 | |
426 | theCommands.Add ("proximity", |
427 | "proximity Shape1 Shape2 [-tol <value>] [-profile]" |
428 | "\n\t\t: Searches for pairs of overlapping faces of the given shapes." |
429 | "\n\t\t: The options are:" |
430 | "\n\t\t: -tol : non-negative tolerance value used for overlapping" |
431 | "\n\t\t: test (for zero tolerance, the strict intersection" |
432 | "\n\t\t: test will be performed)" |
433 | "\n\t\t: -profile : outputs execution time for main algorithm stages", |
434 | __FILE__, |
435 | ShapeProximity, |
436 | aGroup); |
ae9a414a |
437 | |
438 | theCommands.Add ("selfintersect", |
439 | "selfintersect Shape [-tol <value>] [-profile]" |
440 | "\n\t\t: Searches for intersected/overlapped faces in the given shape." |
441 | "\n\t\t: The algorithm uses shape tessellation (should be computed in" |
442 | "\n\t\t: advance), and provides approximate results. The options are:" |
443 | "\n\t\t: -tol : non-negative tolerance value used for overlapping" |
444 | "\n\t\t: test (for zero tolerance, the strict intersection" |
445 | "\n\t\t: test will be performed)" |
446 | "\n\t\t: -profile : outputs execution time for main algorithm stages", |
447 | __FILE__, |
448 | ShapeSelfIntersection, |
449 | aGroup); |
7fd59977 |
450 | } |