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 //=======================================================================
138 //function : BRepPrim_GWedge
139 //purpose : build a box
140 //=======================================================================
142 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
144 const Standard_Real dx,
145 const Standard_Real dy,
146 const Standard_Real dz) :
160 for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
161 if ( ( dx <= Precision::Confusion() ) ||
162 ( dy <= Precision::Confusion() ) ||
163 ( dz <= Precision::Confusion() ) )
164 throw Standard_DomainError();
165 BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
166 WiresBuilt,FacesBuilt);
169 //=======================================================================
170 //function : BRepPrim_GWedge
171 //purpose : build a STEP wedge
172 //=======================================================================
174 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
176 const Standard_Real dx,
177 const Standard_Real dy,
178 const Standard_Real dz,
179 const Standard_Real ltx) :
193 for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
194 if ( ( dx <= Precision::Confusion() ) ||
195 ( dy <= Precision::Confusion() ) ||
196 ( dz <= Precision::Confusion() ) ||
198 throw Standard_DomainError();
199 BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
200 WiresBuilt,FacesBuilt);
203 //=======================================================================
204 //function : BRepPrim_GWedge
205 //purpose : build a wedge by giving all the fields
206 //=======================================================================
208 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
210 const Standard_Real xmin,
211 const Standard_Real ymin,
212 const Standard_Real zmin,
213 const Standard_Real z2min,
214 const Standard_Real x2min,
215 const Standard_Real xmax,
216 const Standard_Real ymax,
217 const Standard_Real zmax,
218 const Standard_Real z2max,
219 const Standard_Real x2max) :
233 for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
234 if ( ( XMax-XMin <= Precision::Confusion() ) ||
235 ( YMax-YMin <= Precision::Confusion() ) ||
236 ( ZMax-ZMin <= Precision::Confusion() ) ||
237 ( Z2Max-Z2Min < 0 ) ||
238 ( X2Max-X2Min < 0 ) )
239 throw Standard_DomainError();
240 BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
241 WiresBuilt,FacesBuilt);
244 //=======================================================================
246 // GetXMin, GetYMin, GetZMin, GetZ2Min, GetX2Min
247 // GetXMax, GetYMax, GetZMax, GetZ2Max, GetX2Max
249 //=======================================================================
251 gp_Ax2 BRepPrim_GWedge::Axes () const { return myAxes; }
252 Standard_Real BRepPrim_GWedge::GetXMin () const { return XMin; }
253 Standard_Real BRepPrim_GWedge::GetYMin () const { return YMin; }
254 Standard_Real BRepPrim_GWedge::GetZMin () const { return ZMin; }
255 Standard_Real BRepPrim_GWedge::GetZ2Min () const { return Z2Min; }
256 Standard_Real BRepPrim_GWedge::GetX2Min () const { return X2Min; }
257 Standard_Real BRepPrim_GWedge::GetXMax () const { return XMax; }
258 Standard_Real BRepPrim_GWedge::GetYMax () const { return YMax; }
259 Standard_Real BRepPrim_GWedge::GetZMax () const { return ZMax; }
260 Standard_Real BRepPrim_GWedge::GetZ2Max () const { return Z2Max; }
261 Standard_Real BRepPrim_GWedge::GetX2Max () const { return X2Max; }
263 //=======================================================================
266 //=======================================================================
268 void BRepPrim_GWedge::Open (const BRepPrim_Direction d1)
270 BRepPrim_Wedge_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
271 myInfinite[BRepPrim_Wedge_NumDir1(d1)] = Standard_True;
274 //=======================================================================
277 //=======================================================================
279 void BRepPrim_GWedge::Close (const BRepPrim_Direction d1)
281 BRepPrim_Wedge_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
282 myInfinite[BRepPrim_Wedge_NumDir1(d1)] = Standard_False;
285 //=======================================================================
286 //function : IsInfinite
287 //purpose : true if it is open in the given direction
288 //=======================================================================
290 Standard_Boolean BRepPrim_GWedge::IsInfinite (const BRepPrim_Direction d1) const
291 { return myInfinite[BRepPrim_Wedge_NumDir1(d1)]; }
293 //=======================================================================
296 //=======================================================================
298 const TopoDS_Shell& BRepPrim_GWedge::Shell() {
300 myBuilder.MakeShell(myShell);
302 if (HasFace(BRepPrim_XMin))
303 myBuilder.AddShellFace(myShell,Face(BRepPrim_XMin));
304 if (HasFace(BRepPrim_XMax))
305 myBuilder.AddShellFace(myShell,Face(BRepPrim_XMax));
306 if (HasFace(BRepPrim_YMin))
307 myBuilder.AddShellFace(myShell,Face(BRepPrim_YMin));
308 if (HasFace(BRepPrim_YMax))
309 myBuilder.AddShellFace(myShell,Face(BRepPrim_YMax));
310 if (HasFace(BRepPrim_ZMin))
311 myBuilder.AddShellFace(myShell,Face(BRepPrim_ZMin));
312 if (HasFace(BRepPrim_ZMax))
313 myBuilder.AddShellFace(myShell,Face(BRepPrim_ZMax));
315 myShell.Closed (BRep_Tool::IsClosed (myShell));
316 myBuilder.CompleteShell(myShell);
317 ShellBuilt = Standard_True;
322 //=======================================================================
324 //purpose : true if the face exist in one direction
325 //=======================================================================
327 Standard_Boolean BRepPrim_GWedge::HasFace (const BRepPrim_Direction d1) const
329 Standard_Boolean state = !myInfinite[BRepPrim_Wedge_NumDir1(d1)];
330 if ( d1 == BRepPrim_YMax ) state = state && ( Z2Max != Z2Min )
331 && ( X2Max != X2Min );
335 //=======================================================================
338 //=======================================================================
340 gp_Pln BRepPrim_GWedge::Plane(const BRepPrim_Direction d1)
343 Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
346 gp_Vec VX = myAxes.XDirection();
347 gp_Vec VY = myAxes.YDirection();
348 gp_Vec VZ = myAxes.Direction();
353 D = myAxes.XDirection();
357 D = myAxes.YDirection();
361 D = myAxes.Direction();
365 Standard_Real X = 0., Y = 0., Z = 0.;
374 if ( X2Min != XMin ) D = gp_Dir((YMax-YMin)*VX+(XMin-X2Min)*VY);
382 if ( X2Max != XMax ) D = gp_Dir((YMax-YMin)*VX+(XMax-X2Max)*VY);
404 if ( Z2Min != ZMin ) D = gp_Dir((YMax-YMin)*VZ+(ZMin-Z2Min)*VY);
412 if ( Z2Max != ZMax ) D = gp_Dir((YMax-YMin)*VZ+(ZMax-Z2Max)*VY);
417 gp_Pnt P = myAxes.Location();
418 P.Translate(X*gp_Vec(myAxes.XDirection()));
419 P.Translate(Y*gp_Vec(myAxes.YDirection()));
420 P.Translate(Z*gp_Vec(myAxes.Direction ()));
425 //=======================================================================
427 //purpose : the face in one direction
428 //=======================================================================
430 const TopoDS_Face& BRepPrim_GWedge::Face
431 (const BRepPrim_Direction d1)
434 Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
436 if (!FacesBuilt[i]) {
437 gp_Pln P = Plane(d1);
438 myBuilder.MakeFace(myFaces[i],P);
439 if (HasWire(d1)) myBuilder.AddFaceWire(myFaces[i],Wire(d1));
440 if ( i%2 == 0 ) myBuilder.ReverseFace(myFaces[i]);
444 BRepPrim_Direction dd1 = BRepPrim_ZMin, dd2 = BRepPrim_YMax,
445 dd3 = BRepPrim_ZMax,dd4 = BRepPrim_YMin;
476 gp_Dir DX = P.XAxis().Direction();
477 gp_Dir DY = P.YAxis().Direction();
478 Standard_Real U,V,DU,DV;
479 if (HasEdge(d1,dd4)) {
481 ElSLib::Parameters(P,L.Location(),U,V);
482 DU = L.Direction() * DX;
483 DV = L.Direction() * DY;
484 myBuilder.SetPCurve(myEdges[BRepPrim_Wedge_NumDir2(d1,dd4)],
486 gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
488 if (HasEdge(d1,dd3)) {
490 ElSLib::Parameters(P,L.Location(),U,V);
491 DU = L.Direction() * DX;
492 DV = L.Direction() * DY;
493 myBuilder.SetPCurve(myEdges[BRepPrim_Wedge_NumDir2(d1,dd3)],
495 gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
498 if (HasEdge(d1,dd2)) {
500 ElSLib::Parameters(P,L.Location(),U,V);
501 DU = L.Direction() * DX;
502 DV = L.Direction() * DY;
503 myBuilder.SetPCurve(myEdges[BRepPrim_Wedge_NumDir2(d1,dd2)],
505 gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
508 if (HasEdge(d1,dd1)) {
510 ElSLib::Parameters(P,L.Location(),U,V);
511 DU = L.Direction() * DX;
512 DV = L.Direction() * DY;
513 myBuilder.SetPCurve(myEdges[BRepPrim_Wedge_NumDir2(d1,dd1)],
515 gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
519 myBuilder.CompleteFace(myFaces[i]);
520 FacesBuilt[i] = Standard_True;
527 //=======================================================================
530 //=======================================================================
532 Standard_Boolean BRepPrim_GWedge::HasWire (const BRepPrim_Direction d1) const
534 Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
536 if (myInfinite[i]) return Standard_False;
537 BRepPrim_Direction dd1 = BRepPrim_XMin,dd2 = BRepPrim_YMax,dd3 = BRepPrim_XMax ,dd4 = BRepPrim_ZMin;
570 return HasEdge(d1,dd1)||HasEdge(d1,dd2)||HasEdge(d1,dd3)||HasEdge(d1,dd4);
574 //=======================================================================
577 //=======================================================================
579 const TopoDS_Wire& BRepPrim_GWedge::Wire
580 (const BRepPrim_Direction d1)
582 Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
584 BRepPrim_Direction dd1 = BRepPrim_XMin,dd2 = BRepPrim_YMax,dd3 = BRepPrim_XMax ,dd4 = BRepPrim_ZMin;
586 if (!WiresBuilt[i]) {
617 myBuilder.MakeWire(myWires[i]);
620 myBuilder.AddWireEdge(myWires[i],Edge(d1,dd4),Standard_False);
622 myBuilder.AddWireEdge(myWires[i],Edge(d1,dd3),Standard_False);
624 myBuilder.AddWireEdge(myWires[i],Edge(d1,dd2),Standard_True );
626 myBuilder.AddWireEdge(myWires[i],Edge(d1,dd1),Standard_True );
628 myBuilder.CompleteWire(myWires[i]);
629 WiresBuilt[i] = Standard_True;
636 //=======================================================================
639 //=======================================================================
641 Standard_Boolean BRepPrim_GWedge::HasEdge (const BRepPrim_Direction d1,
642 const BRepPrim_Direction d2) const
644 Standard_Boolean state = !(myInfinite[BRepPrim_Wedge_NumDir1(d1)] ||
645 myInfinite[BRepPrim_Wedge_NumDir1(d2)]);
646 Standard_Integer i = BRepPrim_Wedge_NumDir2(d1,d2);
647 if ( i == 6 || i == 7 ) state = state && ( X2Max != X2Min );
648 else if ( i == 1 || i == 3 ) state = state && ( Z2Max != Z2Min );
652 //=======================================================================
655 //=======================================================================
657 gp_Lin BRepPrim_GWedge::Line
658 (const BRepPrim_Direction d1,
659 const BRepPrim_Direction d2)
661 if (!HasEdge(d1,d2)) throw Standard_DomainError();
663 Standard_Integer i = BRepPrim_Wedge_NumDir2(d1,d2);
665 Standard_Real X =0., Y =0., Z =0.;
668 gp_Vec VX = myAxes.XDirection();
669 gp_Vec VY = myAxes.YDirection();
670 gp_Vec VZ = myAxes.Direction();
675 D = myAxes.Direction();
679 D = myAxes.XDirection();
683 D = myAxes.YDirection();
751 if ( (XMin != X2Min) || (ZMin != Z2Min) )
752 D = gp_Vec( (X2Min-XMin)*VX + (YMax-YMin)*VY + (Z2Min-ZMin)*VZ);
760 if ( (XMin != X2Min) || (ZMax != Z2Max) )
761 D = gp_Vec( (X2Min-XMin)*VX + (YMax-YMin)*VY + (Z2Max-ZMax)*VZ);
769 if ( (XMax != X2Max) || (ZMin != Z2Min) )
770 D = gp_Vec( (X2Max-XMax)*VX + (YMax-YMin)*VY + (Z2Min-ZMin)*VZ);
778 if ( (XMax != X2Max) || (ZMax != Z2Max) )
779 D = gp_Vec(gp_Pnt(XMax,YMin,ZMax),gp_Pnt(X2Max,YMax,Z2Max));
780 D = gp_Vec( (X2Max-XMax)*VX + (YMax-YMin)*VY + (Z2Max-ZMax)*VZ);
785 gp_Pnt P = myAxes.Location();
786 P.Translate(X*gp_Vec(myAxes.XDirection()));
787 P.Translate(Y*gp_Vec(myAxes.YDirection()));
788 P.Translate(Z*gp_Vec(myAxes.Direction ()));
789 return gp_Lin(gp_Ax1(P,D));
793 //=======================================================================
796 //=======================================================================
798 const TopoDS_Edge& BRepPrim_GWedge::Edge
799 (const BRepPrim_Direction d1,
800 const BRepPrim_Direction d2)
802 if (!HasEdge(d1,d2)) throw Standard_DomainError();
804 Standard_Integer i = BRepPrim_Wedge_NumDir2(d1,d2);
806 if (!EdgesBuilt[i]) {
808 BRepPrim_Direction dd1 = BRepPrim_XMin ,dd2 = BRepPrim_XMax;
831 gp_Lin L = Line(d1,d2);
832 myBuilder.MakeEdge(myEdges[i],L);
834 if (HasVertex(d1,d2,dd2)) {
835 myBuilder.AddEdgeVertex(myEdges[i],Vertex(d1,d2,dd2),
836 ElCLib::Parameter(L,Point(d1,d2,dd2)),
839 if (HasVertex(d1,d2,dd1)) {
840 myBuilder.AddEdgeVertex(myEdges[i],Vertex(d1,d2,dd1),
841 ElCLib::Parameter(L,Point(d1,d2,dd1)),
845 if ( Z2Max == Z2Min ) {
847 myEdges[7] = myEdges[6];
848 EdgesBuilt[7] = Standard_True;
851 myEdges[6] = myEdges[7];
852 EdgesBuilt[6] = Standard_True;
855 if ( X2Max == X2Min ) {
857 myEdges[3] = myEdges[1];
858 EdgesBuilt[3] = Standard_True;
861 myEdges[1] = myEdges[3];
862 EdgesBuilt[1] = Standard_True;
866 myBuilder.CompleteEdge(myEdges[i]);
867 EdgesBuilt[i] = Standard_True;
874 //=======================================================================
875 //function : HasVertex
877 //=======================================================================
879 Standard_Boolean BRepPrim_GWedge::HasVertex
880 (const BRepPrim_Direction d1,
881 const BRepPrim_Direction d2,
882 const BRepPrim_Direction d3) const
883 { return !(myInfinite[BRepPrim_Wedge_NumDir1(d1)] ||
884 myInfinite[BRepPrim_Wedge_NumDir1(d2)] ||
885 myInfinite[BRepPrim_Wedge_NumDir1(d3)]); }
887 //=======================================================================
890 //=======================================================================
892 gp_Pnt BRepPrim_GWedge::Point
893 (const BRepPrim_Direction d1,
894 const BRepPrim_Direction d2,
895 const BRepPrim_Direction d3)
897 if (!HasVertex(d1,d2,d3)) throw Standard_DomainError();
899 Standard_Integer i = BRepPrim_Wedge_NumDir3(d1,d2,d3);
901 Standard_Real X =0., Y =0., Z =0.;
955 gp_Pnt P = myAxes.Location();
956 P.Translate(X*gp_Vec(myAxes.XDirection()));
957 P.Translate(Y*gp_Vec(myAxes.YDirection()));
958 P.Translate(Z*gp_Vec(myAxes.Direction ()));
962 //=======================================================================
965 //=======================================================================
967 const TopoDS_Vertex& BRepPrim_GWedge::Vertex
968 (const BRepPrim_Direction d1,
969 const BRepPrim_Direction d2,
970 const BRepPrim_Direction d3)
972 if (!HasVertex(d1,d2,d3)) throw Standard_DomainError();
974 Standard_Integer i = BRepPrim_Wedge_NumDir3(d1,d2,d3);
976 if (!VerticesBuilt[i]) {
978 myBuilder.MakeVertex(myVertices[i],Point(d1,d2,d3));
980 if ( Z2Max == Z2Min ) {
981 if ( i == 2 || i == 6 ) {
982 myVertices[3] = myVertices[2];
983 myVertices[7] = myVertices[6];
984 VerticesBuilt[3] = Standard_True;
985 VerticesBuilt[7] = Standard_True;
987 else if ( i == 3 || i == 7 ) {
988 myVertices[2] = myVertices[3];
989 myVertices[6] = myVertices[7];
990 VerticesBuilt[2] = Standard_True;
991 VerticesBuilt[6] = Standard_True;
994 if ( X2Max == X2Min ) {
995 if ( i == 2 || i == 3 ) {
996 myVertices[6] = myVertices[2];
997 myVertices[7] = myVertices[3];
998 VerticesBuilt[6] = Standard_True;
999 VerticesBuilt[7] = Standard_True;
1001 else if ( i == 6 || i == 7 ) {
1002 myVertices[2] = myVertices[6];
1003 myVertices[3] = myVertices[7];
1004 VerticesBuilt[2] = Standard_True;
1005 VerticesBuilt[3] = Standard_True;
1009 VerticesBuilt[i] = Standard_True;
1012 return myVertices[i];