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