1 // Created on: 1991-09-27
2 // Created by: Christophe MARION
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRepPrim_Builder.hxx>
19 #include <BRepPrim_Direction.hxx>
20 #include <BRepPrim_GWedge.hxx>
28 #include <Precision.hxx>
29 #include <Standard_DomainError.hxx>
30 #include <Standard_OutOfRange.hxx>
31 #include <TopoDS_Edge.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Shell.hxx>
34 #include <TopoDS_Vertex.hxx>
35 #include <TopoDS_Wire.hxx>
42 static const Standard_Integer num[6] = {0,1,2,3,4,5};
43 static const Standard_Integer val[6] = {0,4,0,2,0,1};
44 static const Standard_Integer tab[6][6] = {{-1,-1, 0, 1, 8, 9},
51 //=======================================================================
52 //function : BRepPrim_Wedge_NumDir1
53 //purpose : when giving a direction return the range of the face
54 //=======================================================================
56 static Standard_Integer BRepPrim_Wedge_NumDir1
57 (const BRepPrim_Direction d1) { return num[d1]; }
59 //=======================================================================
60 //function : BRepPrim_Wedge_NumDir2
61 //purpose : when giving two directions return the range of the edge
62 //=======================================================================
64 static Standard_Integer BRepPrim_Wedge_NumDir2
65 (const BRepPrim_Direction d1,
66 const BRepPrim_Direction d2)
68 Standard_Integer i1 = BRepPrim_Wedge_NumDir1(d1);
69 Standard_Integer i2 = BRepPrim_Wedge_NumDir1(d2);
70 if ( i1/2 == i2/2 ) throw Standard_DomainError();
74 //=======================================================================
75 //function : BRepPrim_Wedge_NumDir3
76 //purpose : when giving three directions return the range of the vertex
77 //=======================================================================
79 static Standard_Integer BRepPrim_Wedge_NumDir3
80 (const BRepPrim_Direction d1,
81 const BRepPrim_Direction d2,
82 const BRepPrim_Direction d3)
84 Standard_Integer i1 = BRepPrim_Wedge_NumDir1(d1);
85 Standard_Integer i2 = BRepPrim_Wedge_NumDir1(d2);
86 Standard_Integer i3 = BRepPrim_Wedge_NumDir1(d3);
87 if (( i1/2 == i2/2 ) ||
89 ( i3/2 == i1/2 )) throw Standard_DomainError();
90 return val[i1]+val[i2]+val[i3];
93 //=======================================================================
94 //function : BRepPrim_Wedge_Check
95 //purpose : raise Standard_DomainError if something was built
96 //=======================================================================
98 static void BRepPrim_Wedge_Check(const Standard_Boolean V[],
99 const Standard_Boolean E[],
100 const Standard_Boolean W[],
101 const Standard_Boolean F[])
104 for (i = 0; i < NBVERTICES; i++)
105 if (V[i]) throw Standard_DomainError();
106 for (i = 0; i < NBEDGES; i++)
107 if (E[i]) throw Standard_DomainError();
108 for (i = 0; i < NBWIRES; i++)
109 if (W[i]) throw Standard_DomainError();
110 for (i = 0; i < NBFACES; i++)
111 if (F[i]) throw Standard_DomainError();
114 //=======================================================================
115 //function : BRepPrim_Wedge_Init
116 //purpose : Set arrays to Standard_False
117 //=======================================================================
119 static void BRepPrim_Wedge_Init(Standard_Boolean& S,
120 Standard_Boolean V[],
121 Standard_Boolean E[],
122 Standard_Boolean W[],
123 Standard_Boolean F[])
127 for (i = 0; i < NBVERTICES; i++)
128 V[i] = Standard_False;
129 for (i = 0; i < NBEDGES; i++)
130 E[i] = Standard_False;
131 for (i = 0; i < NBWIRES; i++)
132 W[i] = Standard_False;
133 for (i = 0; i < NBFACES; i++)
134 F[i] = Standard_False;
137 BRepPrim_GWedge::BRepPrim_GWedge() :
149 for (Standard_Integer i = 0; i < NBFACES; i++)
151 myInfinite[i]=Standard_False;
154 BRepPrim_Wedge_Init (ShellBuilt,VerticesBuilt,EdgesBuilt,
155 WiresBuilt,FacesBuilt);
158 //=======================================================================
159 //function : BRepPrim_GWedge
160 //purpose : build a box
161 //=======================================================================
163 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
165 const Standard_Real dx,
166 const Standard_Real dy,
167 const Standard_Real dz) :
181 for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
183 BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
184 WiresBuilt,FacesBuilt);
187 //=======================================================================
188 //function : BRepPrim_GWedge
189 //purpose : build a STEP wedge
190 //=======================================================================
192 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
194 const Standard_Real dx,
195 const Standard_Real dy,
196 const Standard_Real dz,
197 const Standard_Real ltx) :
211 for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
213 BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
214 WiresBuilt,FacesBuilt);
217 //=======================================================================
218 //function : BRepPrim_GWedge
219 //purpose : build a wedge by giving all the fields
220 //=======================================================================
222 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
224 const Standard_Real xmin,
225 const Standard_Real ymin,
226 const Standard_Real zmin,
227 const Standard_Real z2min,
228 const Standard_Real x2min,
229 const Standard_Real xmax,
230 const Standard_Real ymax,
231 const Standard_Real zmax,
232 const Standard_Real z2max,
233 const Standard_Real x2max) :
247 for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
249 BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
250 WiresBuilt,FacesBuilt);
253 //=======================================================================
255 // GetXMin, GetYMin, GetZMin, GetZ2Min, GetX2Min
256 // GetXMax, GetYMax, GetZMax, GetZ2Max, GetX2Max
258 //=======================================================================
260 gp_Ax2 BRepPrim_GWedge::Axes () const { return myAxes; }
261 Standard_Real BRepPrim_GWedge::GetXMin () const { return XMin; }
262 Standard_Real BRepPrim_GWedge::GetYMin () const { return YMin; }
263 Standard_Real BRepPrim_GWedge::GetZMin () const { return ZMin; }
264 Standard_Real BRepPrim_GWedge::GetZ2Min () const { return Z2Min; }
265 Standard_Real BRepPrim_GWedge::GetX2Min () const { return X2Min; }
266 Standard_Real BRepPrim_GWedge::GetXMax () const { return XMax; }
267 Standard_Real BRepPrim_GWedge::GetYMax () const { return YMax; }
268 Standard_Real BRepPrim_GWedge::GetZMax () const { return ZMax; }
269 Standard_Real BRepPrim_GWedge::GetZ2Max () const { return Z2Max; }
270 Standard_Real BRepPrim_GWedge::GetX2Max () const { return X2Max; }
272 //=======================================================================
275 //=======================================================================
277 void BRepPrim_GWedge::Open (const BRepPrim_Direction d1)
279 BRepPrim_Wedge_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
280 myInfinite[BRepPrim_Wedge_NumDir1(d1)] = Standard_True;
283 //=======================================================================
286 //=======================================================================
288 void BRepPrim_GWedge::Close (const BRepPrim_Direction d1)
290 BRepPrim_Wedge_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
291 myInfinite[BRepPrim_Wedge_NumDir1(d1)] = Standard_False;
294 //=======================================================================
295 //function : IsInfinite
296 //purpose : true if it is open in the given direction
297 //=======================================================================
299 Standard_Boolean BRepPrim_GWedge::IsInfinite (const BRepPrim_Direction d1) const
300 { return myInfinite[BRepPrim_Wedge_NumDir1(d1)]; }
302 //=======================================================================
305 //=======================================================================
307 const TopoDS_Shell& BRepPrim_GWedge::Shell() {
308 if (IsDegeneratedShape())
309 throw Standard_DomainError();
312 myBuilder.MakeShell(myShell);
314 if (HasFace(BRepPrim_XMin))
315 myBuilder.AddShellFace(myShell,Face(BRepPrim_XMin));
316 if (HasFace(BRepPrim_XMax))
317 myBuilder.AddShellFace(myShell,Face(BRepPrim_XMax));
318 if (HasFace(BRepPrim_YMin))
319 myBuilder.AddShellFace(myShell,Face(BRepPrim_YMin));
320 if (HasFace(BRepPrim_YMax))
321 myBuilder.AddShellFace(myShell,Face(BRepPrim_YMax));
322 if (HasFace(BRepPrim_ZMin))
323 myBuilder.AddShellFace(myShell,Face(BRepPrim_ZMin));
324 if (HasFace(BRepPrim_ZMax))
325 myBuilder.AddShellFace(myShell,Face(BRepPrim_ZMax));
327 myShell.Closed (BRep_Tool::IsClosed (myShell));
328 myBuilder.CompleteShell(myShell);
329 ShellBuilt = Standard_True;
334 //=======================================================================
336 //purpose : true if the face exist in one direction
337 //=======================================================================
339 Standard_Boolean BRepPrim_GWedge::HasFace (const BRepPrim_Direction d1) const
341 Standard_Boolean state = !myInfinite[BRepPrim_Wedge_NumDir1(d1)];
342 if ( d1 == BRepPrim_YMax ) state = state && ( Z2Max != Z2Min )
343 && ( X2Max != X2Min );
347 //=======================================================================
350 //=======================================================================
352 gp_Pln BRepPrim_GWedge::Plane(const BRepPrim_Direction d1)
355 Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
358 gp_Vec VX = myAxes.XDirection();
359 gp_Vec VY = myAxes.YDirection();
360 gp_Vec VZ = myAxes.Direction();
365 D = myAxes.XDirection();
369 D = myAxes.YDirection();
373 D = myAxes.Direction();
377 Standard_Real X = 0., Y = 0., Z = 0.;
386 if ( X2Min != XMin ) D = gp_Dir((YMax-YMin)*VX+(XMin-X2Min)*VY);
394 if ( X2Max != XMax ) D = gp_Dir((YMax-YMin)*VX+(XMax-X2Max)*VY);
416 if ( Z2Min != ZMin ) D = gp_Dir((YMax-YMin)*VZ+(ZMin-Z2Min)*VY);
424 if ( Z2Max != ZMax ) D = gp_Dir((YMax-YMin)*VZ+(ZMax-Z2Max)*VY);
429 gp_Pnt P = myAxes.Location();
430 P.Translate(X*gp_Vec(myAxes.XDirection()));
431 P.Translate(Y*gp_Vec(myAxes.YDirection()));
432 P.Translate(Z*gp_Vec(myAxes.Direction ()));
437 //=======================================================================
439 //purpose : the face in one direction
440 //=======================================================================
442 const TopoDS_Face& BRepPrim_GWedge::Face
443 (const BRepPrim_Direction d1)
446 Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
448 if (!FacesBuilt[i]) {
449 gp_Pln P = Plane(d1);
450 myBuilder.MakeFace(myFaces[i],P);
451 if (HasWire(d1)) myBuilder.AddFaceWire(myFaces[i],Wire(d1));
452 if ( i%2 == 0 ) myBuilder.ReverseFace(myFaces[i]);
456 BRepPrim_Direction dd1 = BRepPrim_ZMin, dd2 = BRepPrim_YMax,
457 dd3 = BRepPrim_ZMax,dd4 = BRepPrim_YMin;
488 gp_Dir DX = P.XAxis().Direction();
489 gp_Dir DY = P.YAxis().Direction();
490 Standard_Real U,V,DU,DV;
491 if (HasEdge(d1,dd4)) {
493 ElSLib::Parameters(P,L.Location(),U,V);
494 DU = L.Direction() * DX;
495 DV = L.Direction() * DY;
496 myBuilder.SetPCurve(myEdges[BRepPrim_Wedge_NumDir2(d1,dd4)],
498 gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
500 if (HasEdge(d1,dd3)) {
502 ElSLib::Parameters(P,L.Location(),U,V);
503 DU = L.Direction() * DX;
504 DV = L.Direction() * DY;
505 myBuilder.SetPCurve(myEdges[BRepPrim_Wedge_NumDir2(d1,dd3)],
507 gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
510 if (HasEdge(d1,dd2)) {
512 ElSLib::Parameters(P,L.Location(),U,V);
513 DU = L.Direction() * DX;
514 DV = L.Direction() * DY;
515 myBuilder.SetPCurve(myEdges[BRepPrim_Wedge_NumDir2(d1,dd2)],
517 gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
520 if (HasEdge(d1,dd1)) {
522 ElSLib::Parameters(P,L.Location(),U,V);
523 DU = L.Direction() * DX;
524 DV = L.Direction() * DY;
525 myBuilder.SetPCurve(myEdges[BRepPrim_Wedge_NumDir2(d1,dd1)],
527 gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
531 myBuilder.CompleteFace(myFaces[i]);
532 FacesBuilt[i] = Standard_True;
539 //=======================================================================
542 //=======================================================================
544 Standard_Boolean BRepPrim_GWedge::HasWire (const BRepPrim_Direction d1) const
546 Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
548 if (myInfinite[i]) return Standard_False;
549 BRepPrim_Direction dd1 = BRepPrim_XMin,dd2 = BRepPrim_YMax,dd3 = BRepPrim_XMax ,dd4 = BRepPrim_ZMin;
582 return HasEdge(d1,dd1)||HasEdge(d1,dd2)||HasEdge(d1,dd3)||HasEdge(d1,dd4);
586 //=======================================================================
589 //=======================================================================
591 const TopoDS_Wire& BRepPrim_GWedge::Wire
592 (const BRepPrim_Direction d1)
594 Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
596 BRepPrim_Direction dd1 = BRepPrim_XMin,dd2 = BRepPrim_YMax,dd3 = BRepPrim_XMax ,dd4 = BRepPrim_ZMin;
598 if (!WiresBuilt[i]) {
629 myBuilder.MakeWire(myWires[i]);
632 myBuilder.AddWireEdge(myWires[i],Edge(d1,dd4),Standard_False);
634 myBuilder.AddWireEdge(myWires[i],Edge(d1,dd3),Standard_False);
636 myBuilder.AddWireEdge(myWires[i],Edge(d1,dd2),Standard_True );
638 myBuilder.AddWireEdge(myWires[i],Edge(d1,dd1),Standard_True );
640 myBuilder.CompleteWire(myWires[i]);
641 WiresBuilt[i] = Standard_True;
648 //=======================================================================
651 //=======================================================================
653 Standard_Boolean BRepPrim_GWedge::HasEdge (const BRepPrim_Direction d1,
654 const BRepPrim_Direction d2) const
656 Standard_Boolean state = !(myInfinite[BRepPrim_Wedge_NumDir1(d1)] ||
657 myInfinite[BRepPrim_Wedge_NumDir1(d2)]);
658 Standard_Integer i = BRepPrim_Wedge_NumDir2(d1,d2);
659 if ( i == 6 || i == 7 ) state = state && ( X2Max != X2Min );
660 else if ( i == 1 || i == 3 ) state = state && ( Z2Max != Z2Min );
664 //=======================================================================
667 //=======================================================================
669 gp_Lin BRepPrim_GWedge::Line
670 (const BRepPrim_Direction d1,
671 const BRepPrim_Direction d2)
673 if (!HasEdge(d1,d2)) throw Standard_DomainError();
675 Standard_Integer i = BRepPrim_Wedge_NumDir2(d1,d2);
677 Standard_Real X =0., Y =0., Z =0.;
680 gp_Vec VX = myAxes.XDirection();
681 gp_Vec VY = myAxes.YDirection();
682 gp_Vec VZ = myAxes.Direction();
687 D = myAxes.Direction();
691 D = myAxes.XDirection();
695 D = myAxes.YDirection();
763 if ( (XMin != X2Min) || (ZMin != Z2Min) )
765 D = gp_Vec( (X2Min-XMin)*VX + (YMax-YMin)*VY + (Z2Min-ZMin)*VZ);
774 if ( (XMin != X2Min) || (ZMax != Z2Max) )
776 D = gp_Vec( (X2Min-XMin)*VX + (YMax-YMin)*VY + (Z2Max-ZMax)*VZ);
785 if ( (XMax != X2Max) || (ZMin != Z2Min) )
787 D = gp_Vec( (X2Max-XMax)*VX + (YMax-YMin)*VY + (Z2Min-ZMin)*VZ);
796 if ( (XMax != X2Max) || (ZMax != Z2Max) )
798 D = gp_Vec( (X2Max-XMax)*VX + (YMax-YMin)*VY + (Z2Max-ZMax)*VZ);
804 gp_Pnt P = myAxes.Location();
805 P.Translate(X*gp_Vec(myAxes.XDirection()));
806 P.Translate(Y*gp_Vec(myAxes.YDirection()));
807 P.Translate(Z*gp_Vec(myAxes.Direction ()));
808 return gp_Lin(gp_Ax1(P,D));
812 //=======================================================================
815 //=======================================================================
817 const TopoDS_Edge& BRepPrim_GWedge::Edge
818 (const BRepPrim_Direction d1,
819 const BRepPrim_Direction d2)
821 if (!HasEdge(d1,d2)) throw Standard_DomainError();
823 Standard_Integer i = BRepPrim_Wedge_NumDir2(d1,d2);
825 if (!EdgesBuilt[i]) {
827 BRepPrim_Direction dd1 = BRepPrim_XMin ,dd2 = BRepPrim_XMax;
850 gp_Lin L = Line(d1,d2);
851 myBuilder.MakeEdge(myEdges[i],L);
853 if (HasVertex(d1,d2,dd2)) {
854 myBuilder.AddEdgeVertex(myEdges[i],Vertex(d1,d2,dd2),
855 ElCLib::Parameter(L,Point(d1,d2,dd2)),
858 if (HasVertex(d1,d2,dd1)) {
859 myBuilder.AddEdgeVertex(myEdges[i],Vertex(d1,d2,dd1),
860 ElCLib::Parameter(L,Point(d1,d2,dd1)),
864 if ( Z2Max == Z2Min ) {
866 myEdges[7] = myEdges[6];
867 EdgesBuilt[7] = Standard_True;
870 myEdges[6] = myEdges[7];
871 EdgesBuilt[6] = Standard_True;
874 if ( X2Max == X2Min ) {
876 myEdges[3] = myEdges[1];
877 EdgesBuilt[3] = Standard_True;
880 myEdges[1] = myEdges[3];
881 EdgesBuilt[1] = Standard_True;
885 myBuilder.CompleteEdge(myEdges[i]);
886 EdgesBuilt[i] = Standard_True;
893 //=======================================================================
894 //function : HasVertex
896 //=======================================================================
898 Standard_Boolean BRepPrim_GWedge::HasVertex
899 (const BRepPrim_Direction d1,
900 const BRepPrim_Direction d2,
901 const BRepPrim_Direction d3) const
902 { return !(myInfinite[BRepPrim_Wedge_NumDir1(d1)] ||
903 myInfinite[BRepPrim_Wedge_NumDir1(d2)] ||
904 myInfinite[BRepPrim_Wedge_NumDir1(d3)]); }
906 //=======================================================================
909 //=======================================================================
911 gp_Pnt BRepPrim_GWedge::Point
912 (const BRepPrim_Direction d1,
913 const BRepPrim_Direction d2,
914 const BRepPrim_Direction d3)
916 if (!HasVertex(d1,d2,d3)) throw Standard_DomainError();
918 Standard_Integer i = BRepPrim_Wedge_NumDir3(d1,d2,d3);
920 Standard_Real X =0., Y =0., Z =0.;
974 gp_Pnt P = myAxes.Location();
975 P.Translate(X*gp_Vec(myAxes.XDirection()));
976 P.Translate(Y*gp_Vec(myAxes.YDirection()));
977 P.Translate(Z*gp_Vec(myAxes.Direction ()));
981 //=======================================================================
984 //=======================================================================
986 const TopoDS_Vertex& BRepPrim_GWedge::Vertex
987 (const BRepPrim_Direction d1,
988 const BRepPrim_Direction d2,
989 const BRepPrim_Direction d3)
991 if (!HasVertex(d1,d2,d3)) throw Standard_DomainError();
993 Standard_Integer i = BRepPrim_Wedge_NumDir3(d1,d2,d3);
995 if (!VerticesBuilt[i]) {
997 myBuilder.MakeVertex(myVertices[i],Point(d1,d2,d3));
999 if ( Z2Max == Z2Min ) {
1000 if ( i == 2 || i == 6 ) {
1001 myVertices[3] = myVertices[2];
1002 myVertices[7] = myVertices[6];
1003 VerticesBuilt[3] = Standard_True;
1004 VerticesBuilt[7] = Standard_True;
1006 else if ( i == 3 || i == 7 ) {
1007 myVertices[2] = myVertices[3];
1008 myVertices[6] = myVertices[7];
1009 VerticesBuilt[2] = Standard_True;
1010 VerticesBuilt[6] = Standard_True;
1013 if ( X2Max == X2Min ) {
1014 if ( i == 2 || i == 3 ) {
1015 myVertices[6] = myVertices[2];
1016 myVertices[7] = myVertices[3];
1017 VerticesBuilt[6] = Standard_True;
1018 VerticesBuilt[7] = Standard_True;
1020 else if ( i == 6 || i == 7 ) {
1021 myVertices[2] = myVertices[6];
1022 myVertices[3] = myVertices[7];
1023 VerticesBuilt[2] = Standard_True;
1024 VerticesBuilt[3] = Standard_True;
1028 VerticesBuilt[i] = Standard_True;
1031 return myVertices[i];
1035 //=======================================================================
1036 //function : IsDegeneratedShape
1038 //=======================================================================
1039 Standard_Boolean BRepPrim_GWedge::IsDegeneratedShape()
1041 if ( ( XMax-XMin <= Precision::Confusion() ) ||
1042 ( YMax-YMin <= Precision::Confusion() ) ||
1043 ( ZMax-ZMin <= Precision::Confusion() ) ||
1044 ( Z2Max-Z2Min < 0 ) ||
1045 ( X2Max-X2Min < 0 ) )
1046 return Standard_True;
1048 return Standard_False;