0023248: Wrong result done by solid classifier algorithm for infinite point
[occt.git] / src / BRepTest / BRepTest_OtherCommands.cxx
CommitLineData
b311480e 1// Created on: 1995-04-13
2// Created by: Jean Yves LEBEY
3// Copyright (c) 1995-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <BRepTest.hxx>
23
24#include <Draw_Interpretor.hxx>
25#include <DBRep.hxx>
a15d6ace 26#include <DrawTrSurf.hxx>
27
28#include <string.h>
29#include <stdio.h>
30
31#include <Standard_ErrorHandler.hxx>
32#include <Precision.hxx>
33#include <TCollection_AsciiString.hxx>
34#include <gp_Lin.hxx>
35#include <gp_Pnt.hxx>
36#include <gp_Dir.hxx>
37#include <gp_Ax1.hxx>
38
39#include <ElCLib.hxx>
40
41#include <TColgp_SequenceOfPnt.hxx>
42
43#include <GeomAbs_JoinType.hxx>
44#include <Geom_Line.hxx>
45
46#include <IntCurvesFace_Intersector.hxx>
47
48#include <TopAbs.hxx>
49#include <TopAbs_Orientation.hxx>
50
51#include <TopoDS.hxx>
7fd59977 52#include <TopoDS_Shape.hxx>
53#include <TopoDS_Compound.hxx>
54#include <TopoDS_CompSolid.hxx>
55#include <TopoDS_Solid.hxx>
56#include <TopoDS_Shell.hxx>
57#include <TopoDS_Face.hxx>
58#include <TopoDS_Wire.hxx>
59#include <TopoDS_Edge.hxx>
60#include <TopoDS_Vertex.hxx>
a15d6ace 61#include <TopoDS_Iterator.hxx>
7fd59977 62
a15d6ace 63#include <BRep_Builder.hxx>
64#include <BRep_Tool.hxx>
7fd59977 65
7fd59977 66#include <TopExp_Explorer.hxx>
a15d6ace 67
68#include <TopTools_ListOfShape.hxx>
69#include <TopTools_ListIteratorOfListOfShape.hxx>
7fd59977 70#include <TopTools_MapOfShape.hxx>
71
a15d6ace 72#include <LocOpe_CSIntersector.hxx>
73#include <LocOpe_SequenceOfLin.hxx>
74#include <LocOpe_PntFace.hxx>
75#include <BRepFeat_MakeDPrism.hxx>
7fd59977 76
a15d6ace 77#include <BRepTools.hxx>
78#include <BRepIntCurveSurface_Inter.hxx>
79#include <BRepOffset.hxx>
80#include <BRepOffset_MakeOffset.hxx>
81#include <BRepClass3d_SolidClassifier.hxx>
82
83static
84 void SampleEdges (const TopoDS_Shape& theShape,
85 TColgp_SequenceOfPnt& theSeq);
86static
87 TopoDS_Face NextFaceForPrism (const TopoDS_Shape& shape,
88 const TopoDS_Shape& basis,
89 const gp_Ax1& ax1);
90static
91 void PrintState (Draw_Interpretor& aDI,
92 const TopAbs_State& aState);
93//
94static Standard_Integer emptyshape(Draw_Interpretor&, Standard_Integer, const char** );
95static Standard_Integer subshape (Draw_Interpretor&, Standard_Integer, const char** );
96static Standard_Integer brepintcs (Draw_Interpretor&, Standard_Integer, const char** );
97static Standard_Integer MakeBoss (Draw_Interpretor&, Standard_Integer, const char** );
98static Standard_Integer MakeShell (Draw_Interpretor&, Standard_Integer, const char** );
99static Standard_Integer xbounds (Draw_Interpretor&, Standard_Integer, const char** );
100static Standard_Integer xclassify (Draw_Interpretor&, Standard_Integer, const char** );
7fd59977 101
102//=======================================================================
a15d6ace 103//function : OtherCommands
104//purpose :
7fd59977 105//=======================================================================
a15d6ace 106void BRepTest::OtherCommands(Draw_Interpretor& theCommands)
107{
108 static Standard_Boolean done = Standard_False;
109 if (done) return;
110 done = Standard_True;
111
112 const char* g = "TOPOLOGY other commands";
113
114 theCommands.Add("shape",
115 "shape name V/E/W/F/Sh/So/CS/C; make a empty shape",__FILE__,emptyshape,g);
7fd59977 116
a15d6ace 117 theCommands.Add("subshape",
118 "subshape name V/E/W/F/Sh/So/CS/C index; get subsshape <index> of given type"
119 ,__FILE__,subshape,g);
120
121 theCommands.Add("BRepIntCS",
122 "Calcul d'intersection entre face et curve : BRepIntCS curve shape"
123 ,__FILE__,brepintcs,g);
124
125 theCommands.Add("makeboss", "create a boss on the shape myS", __FILE__, MakeBoss, g);
126 theCommands.Add("mksh", "create a shell on Shape", __FILE__, MakeShell, g);
127 theCommands.Add("xbounds", "xbounds face", __FILE__, xbounds, g);
128 theCommands.Add("xclassify", "use xclassify Solid [Tolerance=1.e-7]", __FILE__, xclassify, g);
129
130
131}
132//=======================================================================
133//function : emptyshape
134//purpose : shape : shape name V/E/W/F/SH/SO/CS/C
135//=======================================================================
136Standard_Integer emptyshape(Draw_Interpretor& , Standard_Integer n, const char** a)
7fd59977 137{
138 if (n <= 1) return 1;
139
140 BRep_Builder B;
141 TopoDS_Shape S;
142
143 if (n == 3) {
144 TCollection_AsciiString as(a[2]); as.LowerCase();
145 const char* a2 = as.ToCString();
146
147 if ( ! strcmp(a2,"c") ) {
148 TopoDS_Compound SS; B.MakeCompound(SS); S = SS;
149 }
150 else if ( ! strcmp(a2,"cs") ) {
151 TopoDS_CompSolid SS; B.MakeCompSolid(SS); S = SS;
152 }
153 else if ( ! strcmp(a2,"so") ) {
154 TopoDS_Solid SS; B.MakeSolid(SS); S = SS;
155 }
156 else if ( ! strcmp(a2,"sh") ) {
157 TopoDS_Shell SS; B.MakeShell(SS); S = SS;
158 }
159 else if ( ! strcmp(a2,"f") ) {
160 TopoDS_Face SS; B.MakeFace(SS); S = SS;
161 }
162 else if ( ! strcmp(a2,"w") ) {
163 TopoDS_Wire SS; B.MakeWire(SS); S = SS;
164 }
165 else if ( ! strcmp(a2,"e") ) {
166 TopoDS_Edge SS; B.MakeEdge(SS); S = SS;
167 }
168 else if ( ! strcmp(a2,"v") ) {
169 TopoDS_Vertex SS; B.MakeVertex(SS); S = SS;
170 }
171 else {
172 return 1;
173 }
174 }
175
176 const char *shapename = a[1];
177 DBRep::Set(shapename,S);
178 return 0;
179}
180
181//=======================================================================
a15d6ace 182//function : subshape
183//purpose :
7fd59977 184//=======================================================================
a15d6ace 185Standard_Integer subshape(Draw_Interpretor& di, Standard_Integer n, const char** a)
7fd59977 186{
187 if (n <= 2) return 1;
188
189
190 TopoDS_Shape S = DBRep::Get(a[1]);
191 if (S.IsNull()) return 0;
192 char newname[1024];
193 strcpy(newname,a[1]);
194 char* p = newname;
195 while (*p != '\0') p++;
196 *p = '_';
197 p++;
198 Standard_Integer i = 0;
199 if (n == 3) {
200 Standard_Integer isub = atoi(a[2]);
201 TopoDS_Iterator itr(S);
202 while (itr.More()) {
203 i++;
204 if ( i == isub ) {
205 sprintf(p,"%d",i);
206 DBRep::Set(newname,itr.Value());
207 di.AppendElement(newname);
208 break;
209 }
210 itr.Next();
211 }
212 }
213 else {
214 // explode a type
215 TopAbs_ShapeEnum typ;
216 switch (a[2][0]) {
217
218 case 'C' :
219 case 'c' :
220 typ = TopAbs_COMPSOLID;
221 break;
222
223 case 'S' :
224 case 's' :
225 if ((a[2][1] == 'O')||(a[2][1] == 'o'))
226 typ = TopAbs_SOLID;
227 else if ((a[2][1] == 'H')||(a[2][1] == 'h'))
228 typ = TopAbs_SHELL;
229 else
230 return 1;
231 break;
232
233 case 'F' :
234 case 'f' :
235 typ = TopAbs_FACE;
236 break;
237
238 case 'W' :
239 case 'w' :
240 typ = TopAbs_WIRE;
241 break;
242
243 case 'E' :
244 case 'e' :
245 typ = TopAbs_EDGE;
246 break;
247
248 case 'V' :
249 case 'v' :
250 typ = TopAbs_VERTEX;
251 break;
252
253 default :
254 return 1;
255 }
256
257 Standard_Integer isub = atoi(a[3]);
258 TopTools_MapOfShape M;
259 M.Add(S);
260 TopExp_Explorer ex(S,typ);
261 while (ex.More()) {
262 if (M.Add(ex.Current())) {
263 i++;
264 if ( i == isub ) {
265 sprintf(p,"%d",i);
266 DBRep::Set(newname,ex.Current());
267 di.AppendElement(newname);
268 break;
269 }
270 }
271 ex.Next();
272 }
273 }
274 return 0;
275}
7fd59977 276//=======================================================================
a15d6ace 277//function : brepintcs
278//purpose :
7fd59977 279//=======================================================================
a15d6ace 280Standard_Integer brepintcs(Draw_Interpretor& , Standard_Integer n, const char** a)
7fd59977 281{
282 if (n <= 2) return 1;
283 TopoDS_Shape S = DBRep::Get(a[n-1]);
284 if (S.IsNull()) return 3;
285
286 static BRepIntCurveSurface_Inter theAlg;
287 static double tol=1e-6;
288 static int nbpi=0;
289 static gp_Pnt curp;
290
291 if (n==3) {
292 Handle(Geom_Curve) C= DrawTrSurf::GetCurve(a[1]);
293 if (C.IsNull()) return 2;
294 GeomAdaptor_Curve acur(C);
295 theAlg.Init(S, acur, tol);
296 for (; theAlg.More(); theAlg.Next()) {
297 curp=theAlg.Pnt();
298 nbpi++;
299 char name[64];
300 char* temp = name; // pour portage WNT
301 sprintf(temp, "%s_%d", "brics", nbpi);
302 DrawTrSurf::Set(temp, curp);
303 }
304 }
305 else {
306 Handle(Geom_Line) hl;
307 gp_Lin thel;
308 for (Standard_Integer il = 1; il<n ; il++) {
309 hl= Handle(Geom_Line)::DownCast(DrawTrSurf::GetCurve(a[il]));
310 if (!hl.IsNull()) {
311 thel=hl->Lin();
312 theAlg.Init(S, thel, tol);
313 for (; theAlg.More(); theAlg.Next()) {
314 curp=theAlg.Pnt();
315 nbpi++;
316 char name[64];
317 char* temp = name; // pour portage WNT
318 sprintf(temp, "%s_%d", "brics", nbpi);
319 DrawTrSurf::Set(temp, curp);
320 }
321 }
322 }
323 }
324 //POP pour NT
325 return 0;
326}
7fd59977 327//=======================================================================
a15d6ace 328//function : MakeBoss
329//purpose :
7fd59977 330//=======================================================================
a15d6ace 331Standard_Integer MakeBoss(Draw_Interpretor& , Standard_Integer , const char** a)
7fd59977 332{
7fd59977 333 TopoDS_Shape myS = DBRep::Get( a[2] );
334
335 TopoDS_Shape myBasis = DBRep::Get( a[3] ) ;
336
337 Standard_Real ang = -0.05235987901687622;
338
339
340 TopoDS_Face basis = TopoDS::Face(myBasis);
341
342 BRepFeat_MakeDPrism DPRISM(myS, basis, basis, ang, 1, Standard_True);
343
344 TopoDS_Shape myFaceOnShape;
345 gp_Pnt Pnt(0.0, 0.0, 50.0);
346 gp_Dir Dir(-0.0, -0.0, -1.0);
347 gp_Ax1 ax(Pnt, Dir);
348
349 myFaceOnShape = NextFaceForPrism(myS, myBasis, ax);
350
351 DPRISM.Perform (myFaceOnShape);
352 DPRISM.Build();
353
354 if( DPRISM.IsDone() ) DBRep::Set( a[1], DPRISM.Shape() );
355
356 return 0;
357}
7fd59977 358//=======================================================================
a15d6ace 359//function : MakeShell
360//purpose :
7fd59977 361//=======================================================================
a15d6ace 362Standard_Integer MakeShell(Draw_Interpretor& , Standard_Integer , const char** a)
7fd59977 363{
364
365 TopoDS_Shape aShape = DBRep::Get( a[1] );
366 TopTools_ListOfShape Lst;
367 TopExp_Explorer Exp(aShape, TopAbs_FACE);
368 TopoDS_Shape InputShape(DBRep::Get( a[2] ));
369 TopoDS_Face F = TopoDS::Face(InputShape);
370// TopoDS_Face F = TopoDS::Face(DBRep::Get( a[2] ));
371
372 Standard_Real Off = -atof( a[3] );
373
374 BRepOffset_MakeOffset Offset;
375
376 Offset.Initialize( aShape, Off, 1.0e-3, BRepOffset_Skin,
377 Standard_True , Standard_False , GeomAbs_Arc );
378 Offset.AddFace( F );
379 Offset.MakeThickSolid();
380
381 if( Offset.IsDone() ) {
382 // SaveShape::Save(Offset.Shape(), "ss");
383 DBRep::Set( a[1], Offset.Shape() );
384 }
385 return 0;
386}
bd05fabf
S
387//=======================================================================
388//function : xbounds
389//purpose :
390//=======================================================================
391Standard_Integer xbounds(Draw_Interpretor& di, Standard_Integer n, const char** a)
392{
393 if (n<2) {
394 di << "Usage : " << a[0] << " face" << "\n";
395 return 0;
396 }
397 //
398
399 Standard_Real aUMin, aUMax, aVMin, aVMax;
400 TopoDS_Shape aS;
401 TopoDS_Face aF;
402 //
403 aS=DBRep::Get(a[1]);
404 if (aS.IsNull()) {
405 di << " null shapes is not allowed here\n";
406 return 0;
407 }
408 if (aS.ShapeType()!=TopAbs_FACE) {
409 di << " shape" << a[1] <<" must be a face\n";
410 return 0;
411 }
412 //
413 aF=*((TopoDS_Face*)&aS);
414 //
415 BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
416 //
417 TCollection_AsciiString aStr;
418 TCollection_AsciiString sUMin(aUMin);
419 TCollection_AsciiString sUMax(aUMax);
420 TCollection_AsciiString sVMin(aVMin);
421 TCollection_AsciiString sVMax(aVMax);
422 //
423 aStr=aStr+sUMin + "\n";
424 aStr=aStr+sUMax + "\n";
425 aStr=aStr+sVMin + "\n";
426 aStr=aStr+sVMax + "\n";
427 di <<aStr.ToCString();
428 //
429 return 0;
430}
7fd59977 431//=======================================================================
a15d6ace 432//function : xclassify
7fd59977 433//purpose :
434//=======================================================================
a15d6ace 435Standard_Integer xclassify (Draw_Interpretor& aDI, Standard_Integer n, const char** a)
7fd59977 436{
a15d6ace 437 char sbf[512];
438
439 if (n < 2) {
440 aDI<<" use xclassify Solid [Tolerance=1.e-7]\n";
441 return 1;
442 }
443
444 TopoDS_Shape aS = DBRep::Get(a[1]);
445 if (aS.IsNull()) {
446 aDI<<" Null Shape is not allowed here\n";
447 return 0;
448 }
449
450 if (aS.ShapeType()!=TopAbs_SOLID) {
451 aDI<< " Shape type must be SOLID\n";
452 return 0;
453 }
454 //
455 Standard_Real aTol=1.e-7;
456 TopAbs_State aState = TopAbs_UNKNOWN;
457 //
458 aTol=1.e-7;
459 if (n==3) {
460 aTol=atof(a[2]);
461 }
462 //
463 BRepClass3d_SolidClassifier aSC(aS);
464 aSC.PerformInfinitePoint(aTol);
465
466 aState = aSC.State();
467 PrintState(aDI, aState);
468 //
469 return 0;
470}
471//=======================================================================
472//function : PrintState
473//purpose :
474//=======================================================================
475void PrintState (Draw_Interpretor& aDI,
476 const TopAbs_State& aState)
477{
478 aDI<<"state is: ";
479 switch (aState) {
480 case TopAbs_IN:
481 aDI<<"IN\n";
482 break;
483 case TopAbs_OUT:
484 aDI<<"OUT\n";
485 break;
486 case TopAbs_ON:
487 aDI<<"ON\n";
488 break;
489 case TopAbs_UNKNOWN:
490 default:
491 aDI<<"UNKNOWN\n";
492 break;
493 }
7fd59977 494}
7fd59977 495//=======================================================================
496//function : NextFaceForPrism
497//purpose : Search a face from <shape> which intersects with a line of
498// direction <ax1> and location a point of <basis>.
499//=======================================================================
a15d6ace 500TopoDS_Face NextFaceForPrism (const TopoDS_Shape& shape,
501 const TopoDS_Shape& basis,
502 const gp_Ax1& ax1)
7fd59977 503{
504 TopoDS_Face nextFace;
505
506 TColgp_SequenceOfPnt seqPnts;
507 SampleEdges(basis, seqPnts);
508
509 for (Standard_Integer i=1; i<=seqPnts.Length(); i++) {
510 const gp_Pnt& pt = seqPnts(i);
511 // find a axis through a face
512 gp_Dir dir = ax1.Direction();
513 gp_Ax1 ax1b(pt, dir);
514
515 LocOpe_CSIntersector ASI(shape);
516 LocOpe_SequenceOfLin slin;
517 slin.Append(ax1b);
518 ASI.Perform(slin);
519
520 if (ASI.IsDone()) {
521 Standard_Integer no=1, IndFrom, IndTo;
522 TopAbs_Orientation theOr;
523 Standard_Real min = 1.e-04, Tol = -Precision::Confusion();
524 if (ASI.LocalizeAfter (no, min, Tol, theOr, IndFrom, IndTo)) {
525 nextFace = ASI.Point(no, IndFrom).Face();
526 break;
527 }
528 }
529 }
530
531 return nextFace;
532}
533
7fd59977 534
535//=======================================================================
536//function : SampleEdges
537//purpose : Sampling of <theShape>.
538//design : Collect the vertices and points on the edges
539//=======================================================================
a15d6ace 540void SampleEdges (const TopoDS_Shape& theShape, TColgp_SequenceOfPnt& theSeq)
7fd59977 541{
542
543 theSeq.Clear();
544
545
546 TopTools_MapOfShape theMap;
547 TopExp_Explorer exp;
548
549 // Adds all vertices/pnt
550 for (exp.Init(theShape,TopAbs_VERTEX); exp.More(); exp.Next()) {
551 if (theMap.Add(exp.Current())) {
552 theSeq.Append (BRep_Tool::Pnt(TopoDS::Vertex(exp.Current())));
553 }
554 }
555
556 // Computes points on edge, but does not take the extremities into account
557 Standard_Integer NECHANT = 5;
558 Handle(Geom_Curve) C;
559 Standard_Real f,l,prm;
560 for (exp.Init (theShape,TopAbs_EDGE); exp.More(); exp.Next()) {
561 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
562 if (theMap.Add(edg)) {
563 if (!BRep_Tool::Degenerated(edg)) {
564 C = BRep_Tool::Curve(edg,f,l);
565 for (Standard_Integer i=1; i < NECHANT; i++) {
566 prm = ((NECHANT-i)*f+i*l)/NECHANT;
567 theSeq.Append (C->Value(prm));
568 }
569 }
570 }
571 }
572}
573