0031336: Modeling data - extend BRepPrimAPI_MakeBox with planar shape creation
[occt.git] / src / BRepPrim / BRepPrim_GWedge.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRepPrim_Builder.hxx>
19 #include <BRepPrim_Direction.hxx>
20 #include <BRepPrim_GWedge.hxx>
21 #include <ElCLib.hxx>
22 #include <ElSLib.hxx>
23 #include <gp_Ax2.hxx>
24 #include <gp_Lin.hxx>
25 #include <gp_Pln.hxx>
26 #include <gp_Pnt.hxx>
27 #include <gp_Vec.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>
36
37 #define NBFACES 6
38 #define NBWIRES 6
39 #define NBEDGES 12
40 #define NBVERTICES 8
41
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},
45                                            {-1,-1, 2, 3,10,11},
46                                            { 0, 2,-1,-1, 4, 5},
47                                            { 1, 3,-1,-1, 6, 7},
48                                            { 8,10, 4, 6,-1,-1},
49                                            { 9,11, 5, 7,-1,-1}};
50
51 //=======================================================================
52 //function : BRepPrim_Wedge_NumDir1
53 //purpose  : when giving a direction return the range of the face
54 //=======================================================================
55
56 static Standard_Integer BRepPrim_Wedge_NumDir1
57   (const BRepPrim_Direction d1) { return num[d1]; }
58
59 //=======================================================================
60 //function : BRepPrim_Wedge_NumDir2
61 //purpose  : when giving two directions return the range of the edge
62 //=======================================================================
63
64 static Standard_Integer BRepPrim_Wedge_NumDir2
65   (const BRepPrim_Direction d1,
66    const BRepPrim_Direction d2)
67 {
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();
71   return tab[i1][i2];
72 }
73
74 //=======================================================================
75 //function : BRepPrim_Wedge_NumDir3
76 //purpose  : when giving three directions return the range of the vertex
77 //=======================================================================
78
79 static Standard_Integer BRepPrim_Wedge_NumDir3
80   (const BRepPrim_Direction d1,
81    const BRepPrim_Direction d2,
82    const BRepPrim_Direction d3)
83 {
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 ) ||
88       ( i2/2 == i3/2 ) ||
89       ( i3/2 == i1/2 )) throw Standard_DomainError();
90   return val[i1]+val[i2]+val[i3];
91 }
92
93 //=======================================================================
94 //function : BRepPrim_Wedge_Check
95 //purpose  : raise Standard_DomainError if something was built
96 //=======================================================================
97
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[])
102 {
103   Standard_Integer i;
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();
112 }
113
114 //=======================================================================
115 //function : BRepPrim_Wedge_Init
116 //purpose  : Set arrays to Standard_False
117 //=======================================================================
118
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[])
124 {
125   Standard_Integer i;
126   S = Standard_False;
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;
135 }
136
137 BRepPrim_GWedge::BRepPrim_GWedge() :
138        XMin (0),
139        XMax (0),
140        YMin (0),
141        YMax (0),
142        ZMin (0),
143        ZMax (0),
144        Z2Min (0),
145        Z2Max (0),
146        X2Min (0),
147        X2Max (0)
148 {
149   for (Standard_Integer i = 0; i < NBFACES; i++)
150   {
151     myInfinite[i]=Standard_False;
152   }
153
154   BRepPrim_Wedge_Init (ShellBuilt,VerticesBuilt,EdgesBuilt,
155                        WiresBuilt,FacesBuilt);
156 }
157
158 //=======================================================================
159 //function : BRepPrim_GWedge
160 //purpose  : build a box
161 //=======================================================================
162
163 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
164                                     const gp_Ax2& Axes,
165                                     const Standard_Real dx,
166                                     const Standard_Real dy,
167                                     const Standard_Real dz) :
168        myBuilder(B),
169        myAxes(Axes),
170        XMin(0),
171        XMax(dx),
172        YMin(0),
173        YMax(dy),
174        ZMin(0),
175        ZMax(dz),
176        Z2Min(0),
177        Z2Max(dz),
178        X2Min(0),
179        X2Max(dx)
180 {
181   for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
182
183   BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
184                         WiresBuilt,FacesBuilt);
185 }
186
187 //=======================================================================
188 //function : BRepPrim_GWedge
189 //purpose  : build a STEP wedge
190 //=======================================================================
191
192 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
193                                     const gp_Ax2& Axes,
194                                     const Standard_Real dx,
195                                     const Standard_Real dy,
196                                     const Standard_Real dz,
197                                     const Standard_Real ltx) :
198        myBuilder(B),
199        myAxes(Axes),
200        XMin(0),
201        XMax(dx),
202        YMin(0),
203        YMax(dy),
204        ZMin(0),
205        ZMax(dz),
206        Z2Min(0),
207        Z2Max(dz),
208        X2Min(0),
209        X2Max(ltx)
210 {
211   for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
212
213   BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
214                         WiresBuilt,FacesBuilt);
215 }
216
217 //=======================================================================
218 //function : BRepPrim_GWedge
219 //purpose  : build a wedge by giving all the fields
220 //=======================================================================
221
222 BRepPrim_GWedge::BRepPrim_GWedge (const BRepPrim_Builder& B,
223                                     const gp_Ax2& Axes,
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) :
234        myBuilder(B),
235        myAxes(Axes),
236        XMin(xmin),
237        XMax(xmax),
238        YMin(ymin),
239        YMax(ymax),
240        ZMin(zmin),
241        ZMax(zmax),
242        Z2Min(z2min),
243        Z2Max(z2max),
244        X2Min(x2min),
245        X2Max(x2max)
246 {
247   for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
248
249   BRepPrim_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
250                         WiresBuilt,FacesBuilt);
251 }
252
253 //=======================================================================
254 //function : Axes,
255 //           GetXMin, GetYMin, GetZMin, GetZ2Min, GetX2Min
256 //           GetXMax, GetYMax, GetZMax, GetZ2Max, GetX2Max
257 //purpose  : trivial
258 //=======================================================================
259
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;  }
271
272 //=======================================================================
273 //function : Open
274 //purpose  : trivial
275 //=======================================================================
276
277 void BRepPrim_GWedge::Open (const BRepPrim_Direction d1)
278 {
279   BRepPrim_Wedge_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
280   myInfinite[BRepPrim_Wedge_NumDir1(d1)] = Standard_True;
281 }
282
283 //=======================================================================
284 //function : Close
285 //purpose  : trivial
286 //=======================================================================
287
288 void BRepPrim_GWedge::Close (const BRepPrim_Direction d1)
289 {
290   BRepPrim_Wedge_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
291   myInfinite[BRepPrim_Wedge_NumDir1(d1)] = Standard_False;
292 }
293
294 //=======================================================================
295 //function : IsInfinite
296 //purpose  : true if it is open in the given direction
297 //=======================================================================
298
299 Standard_Boolean BRepPrim_GWedge::IsInfinite (const BRepPrim_Direction d1) const
300 { return myInfinite[BRepPrim_Wedge_NumDir1(d1)]; }
301
302 //=======================================================================
303 //function : Shell
304 //purpose  : 
305 //=======================================================================
306
307 const TopoDS_Shell& BRepPrim_GWedge::Shell() {
308   if (IsDegeneratedShape())
309     throw Standard_DomainError();
310
311   if (!ShellBuilt) {
312     myBuilder.MakeShell(myShell);
313
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));
326
327     myShell.Closed (BRep_Tool::IsClosed (myShell));
328     myBuilder.CompleteShell(myShell);
329     ShellBuilt = Standard_True;
330   }
331   return myShell;
332 }
333
334 //=======================================================================
335 //function : HasFace 
336 //purpose  : true if the face exist in one direction
337 //=======================================================================
338
339 Standard_Boolean BRepPrim_GWedge::HasFace (const BRepPrim_Direction d1) const
340
341   Standard_Boolean state = !myInfinite[BRepPrim_Wedge_NumDir1(d1)]; 
342   if ( d1 == BRepPrim_YMax ) state = state && ( Z2Max != Z2Min )
343                                              && ( X2Max != X2Min );
344   return state;
345 }
346
347 //=======================================================================
348 //function : Plane
349 //purpose  : 
350 //=======================================================================
351
352 gp_Pln BRepPrim_GWedge::Plane(const BRepPrim_Direction d1)
353 {
354
355   Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
356
357   gp_Dir D;
358   gp_Vec VX = myAxes.XDirection();
359   gp_Vec VY = myAxes.YDirection();
360   gp_Vec VZ = myAxes.Direction();
361   
362   switch (i/2) {
363     
364   case 0 :
365     D = myAxes.XDirection();
366     break;
367     
368   case 1 :
369     D = myAxes.YDirection();
370     break;
371     
372   case 2 :
373     D = myAxes.Direction();
374     break;
375     
376   };
377   Standard_Real X = 0., Y = 0., Z = 0.;
378   
379   switch (i) {
380     
381   case 0 :
382     // XMin
383     X = XMin;
384     Y = YMin;
385     Z = ZMin;
386     if ( X2Min != XMin ) D = gp_Dir((YMax-YMin)*VX+(XMin-X2Min)*VY);
387     break;
388     
389   case 1 :
390     // XMax
391     X = XMax;
392     Y = YMin;
393     Z = ZMin;
394     if ( X2Max != XMax )  D = gp_Dir((YMax-YMin)*VX+(XMax-X2Max)*VY);
395     break;
396     
397   case 2 :
398     // YMin
399     X = XMin;
400     Y = YMin;
401     Z = ZMin;
402     break;
403     
404   case 3 :
405     // YMax
406     X = XMin;
407     Y = YMax;
408     Z = ZMin;
409     break;
410     
411   case 4 :
412     // ZMin
413     X = XMin;
414     Y = YMin;
415     Z = ZMin;
416     if ( Z2Min != ZMin ) D = gp_Dir((YMax-YMin)*VZ+(ZMin-Z2Min)*VY);
417     break;
418     
419   case 5 :
420     // ZMax
421     X = XMin;
422     Y = YMin;
423     Z = ZMax;
424     if ( Z2Max != ZMax )  D = gp_Dir((YMax-YMin)*VZ+(ZMax-Z2Max)*VY);
425     break;
426     
427   };
428   
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 ()));
433   gp_Pln plane(P,D);
434   return plane;
435 }
436
437 //=======================================================================
438 //function : Face
439 //purpose  : the face in one direction
440 //=======================================================================
441
442 const TopoDS_Face& BRepPrim_GWedge::Face 
443        (const BRepPrim_Direction d1)
444 {
445
446   Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
447
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]);
453
454     // pcurves
455
456     BRepPrim_Direction dd1 = BRepPrim_ZMin, dd2 = BRepPrim_YMax, 
457     dd3 = BRepPrim_ZMax,dd4 = BRepPrim_YMin;
458
459     switch (i/2) {
460       
461     case 0 :
462       // XMin XMax
463       dd1 = BRepPrim_ZMin;
464       dd2 = BRepPrim_YMax;
465       dd3 = BRepPrim_ZMax;
466       dd4 = BRepPrim_YMin;
467       break;
468       
469     case 1 :
470       // YMin YMax
471       dd1 = BRepPrim_XMin;
472       dd2 = BRepPrim_ZMax;
473       dd3 = BRepPrim_XMax;
474       dd4 = BRepPrim_ZMin;
475       break;
476       
477     case 2 :
478       // ZMin ZMax
479       dd1 = BRepPrim_YMin;
480       dd2 = BRepPrim_XMax;
481       dd3 = BRepPrim_YMax;
482       dd4 = BRepPrim_XMin;
483       break;
484       
485     };
486
487     gp_Lin L;
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)) {
492       L = Line(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)],
497                           myFaces[i],
498                           gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
499     }
500     if (HasEdge(d1,dd3)) {
501       L = Line(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)],
506                           myFaces[i],
507                           gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
508     }
509
510     if (HasEdge(d1,dd2)) {
511       L = Line(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)],
516                           myFaces[i],
517                           gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
518     }
519
520     if (HasEdge(d1,dd1)) {
521       L = Line(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)],
526                           myFaces[i],
527                           gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
528     }
529
530    
531     myBuilder.CompleteFace(myFaces[i]);
532     FacesBuilt[i] = Standard_True;
533   }
534   
535   return myFaces[i];
536   
537 }
538
539 //=======================================================================
540 //function : HasWire
541 //purpose  : trivial
542 //=======================================================================
543
544 Standard_Boolean BRepPrim_GWedge::HasWire (const BRepPrim_Direction d1) const
545 {
546   Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
547
548   if (myInfinite[i]) return Standard_False;
549   BRepPrim_Direction dd1 = BRepPrim_XMin,dd2 = BRepPrim_YMax,dd3 = BRepPrim_XMax ,dd4 = BRepPrim_ZMin;
550
551   switch (i/2) {
552     
553   case 0 :
554     // XMin XMax
555     dd1 = BRepPrim_ZMin;
556     dd2 = BRepPrim_YMax;
557     dd3 = BRepPrim_ZMax;
558     dd4 = BRepPrim_YMin;
559     break;
560     
561   case 1 :
562     // YMin YMax
563     dd1 = BRepPrim_XMin;
564     dd2 = BRepPrim_ZMax;
565     dd3 = BRepPrim_XMax;
566     dd4 = BRepPrim_ZMin;
567     break;
568     
569   case 2 :
570     // ZMin ZMax
571     dd1 = BRepPrim_YMin;
572     dd2 = BRepPrim_XMax;
573     dd3 = BRepPrim_YMax;
574     dd4 = BRepPrim_XMin;
575     break;
576 #ifndef OCCT_DEBUG
577   default:
578     break;
579 #endif
580   };
581
582   return HasEdge(d1,dd1)||HasEdge(d1,dd2)||HasEdge(d1,dd3)||HasEdge(d1,dd4);
583
584 }
585
586 //=======================================================================
587 //function : Wire
588 //purpose  : trivial
589 //=======================================================================
590
591 const TopoDS_Wire& BRepPrim_GWedge::Wire
592        (const BRepPrim_Direction d1)
593 {
594   Standard_Integer i = BRepPrim_Wedge_NumDir1(d1);
595
596   BRepPrim_Direction dd1 = BRepPrim_XMin,dd2 = BRepPrim_YMax,dd3 = BRepPrim_XMax ,dd4 = BRepPrim_ZMin;
597
598   if (!WiresBuilt[i]) {
599
600     switch (i/2) {
601       
602     case 0 :
603       // XMin XMax
604       dd1 = BRepPrim_ZMin;
605       dd2 = BRepPrim_YMax;
606       dd3 = BRepPrim_ZMax;
607       dd4 = BRepPrim_YMin;
608       break;
609       
610     case 1 :
611       // YMin YMax
612       dd1 = BRepPrim_XMin;
613       dd2 = BRepPrim_ZMax;
614       dd3 = BRepPrim_XMax;
615       dd4 = BRepPrim_ZMin;
616       break;
617       
618     case 2 :
619       // ZMin ZMax
620       dd1 = BRepPrim_YMin;
621       dd2 = BRepPrim_XMax;
622       dd3 = BRepPrim_YMax;
623       dd4 = BRepPrim_XMin;
624       break;
625     default:
626       break;
627     };
628
629     myBuilder.MakeWire(myWires[i]);
630   
631     if (HasEdge(d1,dd4))
632       myBuilder.AddWireEdge(myWires[i],Edge(d1,dd4),Standard_False);
633     if (HasEdge(d1,dd3))
634       myBuilder.AddWireEdge(myWires[i],Edge(d1,dd3),Standard_False);
635     if (HasEdge(d1,dd2))
636       myBuilder.AddWireEdge(myWires[i],Edge(d1,dd2),Standard_True );
637     if (HasEdge(d1,dd1))
638       myBuilder.AddWireEdge(myWires[i],Edge(d1,dd1),Standard_True );
639    
640     myBuilder.CompleteWire(myWires[i]);
641     WiresBuilt[i] = Standard_True;
642   }
643    
644   return myWires[i];
645
646 }
647
648 //=======================================================================
649 //function : HasEdge
650 //purpose  : trivial
651 //=======================================================================
652
653 Standard_Boolean BRepPrim_GWedge::HasEdge (const BRepPrim_Direction d1,
654                                    const BRepPrim_Direction d2) const
655 {
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 );
661   return state;
662 }
663
664 //=======================================================================
665 //function : Line
666 //purpose  : trivial
667 //=======================================================================
668
669 gp_Lin BRepPrim_GWedge::Line
670   (const BRepPrim_Direction d1,
671    const BRepPrim_Direction d2)
672 {
673   if (!HasEdge(d1,d2)) throw Standard_DomainError();
674
675   Standard_Integer i = BRepPrim_Wedge_NumDir2(d1,d2);
676
677   Standard_Real X =0., Y =0., Z =0.;
678
679   gp_Dir D;
680   gp_Vec VX = myAxes.XDirection();
681   gp_Vec VY = myAxes.YDirection();
682   gp_Vec VZ = myAxes.Direction();
683
684   switch (i/4) {
685
686   case 0 :
687     D = myAxes.Direction();
688     break;
689
690   case 1 :
691     D = myAxes.XDirection();
692     break;
693
694   case 2 :
695     D = myAxes.YDirection();
696     break;
697
698   };
699
700   switch (i) {
701
702   case 0 :
703     // XMin YMin
704     X = XMin;
705     Y = YMin;
706     Z = ZMin;
707     break;
708
709   case 1 :
710     // XMin YMax
711     X = X2Min;
712     Y = YMax;
713     Z = Z2Min;
714     break;
715
716   case 2 :
717     // XMax YMin
718     X = XMax;
719     Y = YMin;
720     Z = ZMin;
721     break;
722
723   case 3 :
724     // XMax YMax
725     X = X2Max;
726     Y = YMax;
727     Z = Z2Min;
728     break;
729
730   case 4 :
731     // YMin ZMin
732     X = XMin;
733     Y = YMin;
734     Z = ZMin;
735     break;
736
737   case 5 :
738     // YMin ZMax
739     X = XMin;
740     Y = YMin;
741     Z = ZMax;
742     break;
743
744   case 6 :
745     // YMax ZMin
746     X = X2Min;
747     Y = YMax;
748     Z = Z2Min;
749     break;
750
751   case 7 :
752     // YMax ZMax
753     X = X2Min;
754     Y = YMax;
755     Z = Z2Max;
756     break;
757
758   case 8 :
759     // ZMin XMin
760     X = XMin;
761     Y = YMin;
762     Z = ZMin;
763     if ( (XMin != X2Min) || (ZMin != Z2Min) )
764     {
765       D = gp_Vec( (X2Min-XMin)*VX + (YMax-YMin)*VY + (Z2Min-ZMin)*VZ);
766     }
767     break;
768
769   case 9 :
770     // ZMax XMin
771     X = XMin;
772     Y = YMin;
773     Z = ZMax;
774     if ( (XMin != X2Min) || (ZMax != Z2Max) )
775     {
776       D = gp_Vec( (X2Min-XMin)*VX + (YMax-YMin)*VY + (Z2Max-ZMax)*VZ);
777     }
778     break;
779
780   case 10 :
781     // ZMin XMax
782     X = XMax;
783     Y = YMin;
784     Z = ZMin;
785     if ( (XMax != X2Max) || (ZMin != Z2Min) )
786     {
787       D = gp_Vec( (X2Max-XMax)*VX + (YMax-YMin)*VY + (Z2Min-ZMin)*VZ);
788     }
789     break;
790
791   case 11 :
792     // ZMax XMax
793     X = XMax;
794     Y = YMin;
795     Z = ZMax;
796     if ( (XMax != X2Max) || (ZMax != Z2Max) )
797     {
798       D = gp_Vec( (X2Max-XMax)*VX + (YMax-YMin)*VY + (Z2Max-ZMax)*VZ);
799     }
800     break;
801
802   }
803
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));
809
810 }
811
812 //=======================================================================
813 //function : Edge
814 //purpose  : trivial
815 //=======================================================================
816
817 const TopoDS_Edge& BRepPrim_GWedge::Edge
818        (const BRepPrim_Direction d1,
819         const BRepPrim_Direction d2)
820 {
821   if (!HasEdge(d1,d2)) throw Standard_DomainError();
822
823   Standard_Integer i = BRepPrim_Wedge_NumDir2(d1,d2);
824
825   if (!EdgesBuilt[i]) {
826
827     BRepPrim_Direction dd1 = BRepPrim_XMin ,dd2 = BRepPrim_XMax;
828
829     switch (i/4) {
830     
831     case 0 :
832       dd1 = BRepPrim_ZMin;
833       dd2 = BRepPrim_ZMax;
834       break;
835     
836     case 1 :
837       dd1 = BRepPrim_XMin;
838       dd2 = BRepPrim_XMax;
839       break;
840     
841     case 2 :
842       dd1 = BRepPrim_YMin;
843       dd2 = BRepPrim_YMax;
844       break;
845
846     default:
847       break;
848     };
849     
850     gp_Lin L = Line(d1,d2);
851     myBuilder.MakeEdge(myEdges[i],L);
852     
853     if (HasVertex(d1,d2,dd2)) {
854       myBuilder.AddEdgeVertex(myEdges[i],Vertex(d1,d2,dd2),
855                               ElCLib::Parameter(L,Point(d1,d2,dd2)),
856                               Standard_False);
857     }
858     if (HasVertex(d1,d2,dd1)) {
859       myBuilder.AddEdgeVertex(myEdges[i],Vertex(d1,d2,dd1),
860                               ElCLib::Parameter(L,Point(d1,d2,dd1)),
861                               Standard_True );
862     }
863     
864     if ( Z2Max == Z2Min ) {
865       if ( i == 6 ) {
866         myEdges[7]    = myEdges[6];
867         EdgesBuilt[7] = Standard_True;
868       }
869       else if ( i == 7 ) {
870         myEdges[6]    = myEdges[7];
871         EdgesBuilt[6] = Standard_True;
872       }
873     }
874     if ( X2Max == X2Min ) {
875       if ( i == 1 ) {
876         myEdges[3]    = myEdges[1];
877         EdgesBuilt[3] = Standard_True;
878       }
879       else if ( i == 3 ) {
880         myEdges[1]    = myEdges[3];
881         EdgesBuilt[1] = Standard_True;
882       }
883     }
884
885     myBuilder.CompleteEdge(myEdges[i]);
886     EdgesBuilt[i] = Standard_True;
887   }
888
889   return myEdges[i];
890
891 }
892
893 //=======================================================================
894 //function : HasVertex
895 //purpose  : trivial
896 //=======================================================================
897
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)]); }
905
906 //=======================================================================
907 //function : Point
908 //purpose  : trivial
909 //=======================================================================
910
911 gp_Pnt  BRepPrim_GWedge::Point
912   (const BRepPrim_Direction d1,
913    const BRepPrim_Direction d2,
914    const BRepPrim_Direction d3)
915 {
916   if (!HasVertex(d1,d2,d3)) throw Standard_DomainError();
917
918   Standard_Integer i = BRepPrim_Wedge_NumDir3(d1,d2,d3);
919
920   Standard_Real X =0., Y =0., Z =0.;
921
922   switch (i) {
923     
924   case 0 :
925     X = XMin;
926     Y = YMin;
927     Z = ZMin;
928     break;
929     
930   case 1 :
931     X = XMin;
932     Y = YMin;
933     Z = ZMax;
934     break;
935     
936   case 2 :
937     X = X2Min;
938     Y = YMax;
939     Z = Z2Min;
940     break;
941     
942   case 3 :
943     X = X2Min;
944     Y = YMax;
945     Z = Z2Max;
946     break;
947     
948   case 4 :
949     X = XMax;
950     Y = YMin;
951     Z = ZMin;
952     break;
953     
954   case 5 :
955     X = XMax;
956     Y = YMin;
957     Z = ZMax;
958     break;
959     
960   case 6 :
961     X = X2Max;
962     Y = YMax;
963     Z = Z2Min;
964     break;
965
966   case 7 :
967     X = X2Max;
968     Y = YMax;
969     Z = Z2Max;
970     break;
971     
972   };
973
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 ()));
978   return P;
979 }
980
981 //=======================================================================
982 //function : Vertex
983 //purpose  : trivial
984 //=======================================================================
985
986 const TopoDS_Vertex& BRepPrim_GWedge::Vertex 
987        (const BRepPrim_Direction d1,
988         const BRepPrim_Direction d2,
989         const BRepPrim_Direction d3)
990 {
991   if (!HasVertex(d1,d2,d3)) throw Standard_DomainError();
992
993   Standard_Integer i = BRepPrim_Wedge_NumDir3(d1,d2,d3);
994
995   if (!VerticesBuilt[i]) {
996
997     myBuilder.MakeVertex(myVertices[i],Point(d1,d2,d3));
998
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;
1005       }
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;
1011       }
1012     }
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;
1019       }
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;
1025       }
1026     }
1027
1028     VerticesBuilt[i] = Standard_True;
1029   }
1030
1031   return myVertices[i];
1032
1033 }
1034
1035 //=======================================================================
1036 //function : IsDegeneratedShape
1037 //purpose  :
1038 //=======================================================================
1039 Standard_Boolean BRepPrim_GWedge::IsDegeneratedShape()
1040 {
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;
1047   else
1048     return Standard_False;
1049 }
1050