0030346: Modeling Algorithms - BRepPrimAPI_MakeRevol throws "BRepSweep_Translation...
[occt.git] / src / BRepTest / BRepTest_ExtremaCommands.cxx
CommitLineData
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
46static 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 68static 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//==============================================================================
149static 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//==============================================================================
286static 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 404void 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}