0024144: BRepPrimAPI_MakeWedge wrong
[occt.git] / src / Primitives / Primitives_Wedge.gxx
1 // Created on: 1991-09-27
2 // Created by: Christophe MARION
3 // Copyright (c) 1991-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
21
22 #include <Precision.hxx>
23 #include <gp_Vec.hxx>
24 #include <gp_Pln.hxx>
25 #include <gp_Lin.hxx>
26 #include <ElSLib.hxx>
27 #include <ElCLib.hxx>
28
29 #include <Standard_DomainError.hxx>
30 #include <Standard_OutOfRange.hxx>
31
32 #undef Standard_True
33 #undef Standard_False
34
35 #define Standard_True ((Standard_Boolean) 1)
36 #define Standard_False ((Standard_Boolean) 0)
37
38 #define NBFACES 6
39 #define NBWIRES 6
40 #define NBEDGES 12
41 #define NBVERTICES 8
42
43 static const Standard_Integer num[6] = {0,1,2,3,4,5};
44 static const Standard_Integer val[6] = {0,4,0,2,0,1};
45 static const Standard_Integer tab[6][6] = {{-1,-1, 0, 1, 8, 9},
46                                            {-1,-1, 2, 3,10,11},
47                                            { 0, 2,-1,-1, 4, 5},
48                                            { 1, 3,-1,-1, 6, 7},
49                                            { 8,10, 4, 6,-1,-1},
50                                            { 9,11, 5, 7,-1,-1}};
51
52 //=======================================================================
53 //function : Primitives_Wedge_NumDir1
54 //purpose  : when giving a direction return the range of the face
55 //=======================================================================
56
57 static Standard_Integer Primitives_Wedge_NumDir1
58   (const Primitives_Direction d1) { return num[d1]; }
59
60 //=======================================================================
61 //function : Primitives_Wedge_NumDir2
62 //purpose  : when giving two directions return the range of the edge
63 //=======================================================================
64
65 static Standard_Integer Primitives_Wedge_NumDir2
66   (const Primitives_Direction d1,
67    const Primitives_Direction d2)
68 {
69   Standard_Integer i1 = Primitives_Wedge_NumDir1(d1);
70   Standard_Integer i2 = Primitives_Wedge_NumDir1(d2);
71   if ( i1/2 == i2/2 ) Standard_DomainError::Raise();
72   return tab[i1][i2];
73 }
74
75 //=======================================================================
76 //function : Primitives_Wedge_NumDir3
77 //purpose  : when giving three directions return the range of the vertex
78 //=======================================================================
79
80 static Standard_Integer Primitives_Wedge_NumDir3
81   (const Primitives_Direction d1,
82    const Primitives_Direction d2,
83    const Primitives_Direction d3)
84 {
85   Standard_Integer i1 = Primitives_Wedge_NumDir1(d1);
86   Standard_Integer i2 = Primitives_Wedge_NumDir1(d2);
87   Standard_Integer i3 = Primitives_Wedge_NumDir1(d3);
88   if (( i1/2 == i2/2 ) ||
89       ( i2/2 == i3/2 ) ||
90       ( i3/2 == i1/2 )) Standard_DomainError::Raise();
91   return val[i1]+val[i2]+val[i3];
92 }
93
94 //=======================================================================
95 //function : Primitives_Wedge_Check
96 //purpose  : raise Standard_DomainError if something was built
97 //=======================================================================
98
99 static void Primitives_Wedge_Check(const Standard_Boolean V[],
100                                    const Standard_Boolean E[],
101                                    const Standard_Boolean W[],
102                                    const Standard_Boolean F[])
103 {
104   Standard_Integer i;
105   for (i = 0; i < NBVERTICES; i++)
106     if (V[i]) Standard_DomainError::Raise();
107   for (i = 0; i < NBEDGES; i++)
108     if (E[i]) Standard_DomainError::Raise();
109   for (i = 0; i < NBWIRES; i++)
110     if (W[i]) Standard_DomainError::Raise();
111   for (i = 0; i < NBFACES; i++)
112     if (F[i]) Standard_DomainError::Raise();
113 }
114
115 //=======================================================================
116 //function : Primitives_Wedge_Init
117 //purpose  : Set arrays to Standard_False
118 //=======================================================================
119
120 static void Primitives_Wedge_Init(Standard_Boolean& S,
121                                   Standard_Boolean V[],
122                                   Standard_Boolean E[],
123                                   Standard_Boolean W[],
124                                   Standard_Boolean F[])
125 {
126   Standard_Integer i;
127   S = Standard_False;
128   for (i = 0; i < NBVERTICES; i++)
129     V[i] = Standard_False;
130   for (i = 0; i < NBEDGES; i++)
131     E[i] = Standard_False;
132   for (i = 0; i < NBWIRES; i++)
133     W[i] = Standard_False;
134   for (i = 0; i < NBFACES; i++)
135     F[i] = Standard_False;
136 }
137
138 //=======================================================================
139 //function : Primitives_Wedge
140 //purpose  : build a box
141 //=======================================================================
142
143 Primitives_Wedge::Primitives_Wedge (const TheBuilder& B,
144                                     const gp_Ax2& Axes,
145                                     const Standard_Real dx,
146                                     const Standard_Real dy,
147                                     const Standard_Real dz) :
148        myBuilder(B),
149        myAxes(Axes),
150        XMin(0),
151        XMax(dx),
152        YMin(0),
153        YMax(dy),
154        ZMin(0),
155        ZMax(dz),
156        Z2Min(0),
157        Z2Max(dz),
158        X2Min(0),
159        X2Max(dx)
160 {
161   for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
162   if ( ( dx <= Precision::Confusion() ) ||
163        ( dy <= Precision::Confusion() ) ||
164        ( dz <= Precision::Confusion() ) )
165     Standard_DomainError::Raise();
166   Primitives_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
167                         WiresBuilt,FacesBuilt);
168 }
169
170 //=======================================================================
171 //function : Primitives_Wedge
172 //purpose  : build a STEP wedge
173 //=======================================================================
174
175 Primitives_Wedge::Primitives_Wedge (const TheBuilder& B,
176                                     const gp_Ax2& Axes,
177                                     const Standard_Real dx,
178                                     const Standard_Real dy,
179                                     const Standard_Real dz,
180                                     const Standard_Real ltx) :
181        myBuilder(B),
182        myAxes(Axes),
183        XMin(0),
184        XMax(dx),
185        YMin(0),
186        YMax(dy),
187        ZMin(0),
188        ZMax(dz),
189        Z2Min(0),
190        Z2Max(dz),
191        X2Min(0),
192        X2Max(ltx)
193 {
194   for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
195   if ( ( dx <= Precision::Confusion() ) ||
196        ( dy <= Precision::Confusion() ) ||
197        ( dz <= Precision::Confusion() ) ||
198        ( ltx < 0 ) )
199     Standard_DomainError::Raise();
200   Primitives_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
201                         WiresBuilt,FacesBuilt);
202 }
203
204 //=======================================================================
205 //function : Primitives_Wedge
206 //purpose  : build a wedge by giving all the fields
207 //=======================================================================
208
209 Primitives_Wedge::Primitives_Wedge (const TheBuilder& B,
210                                     const gp_Ax2& Axes,
211                                     const Standard_Real xmin,
212                                     const Standard_Real ymin,
213                                     const Standard_Real zmin,
214                                     const Standard_Real z2min,
215                                     const Standard_Real x2min,
216                                     const Standard_Real xmax,
217                                     const Standard_Real ymax,
218                                     const Standard_Real zmax,
219                                     const Standard_Real z2max,
220                                     const Standard_Real x2max) :
221        myBuilder(B),
222        myAxes(Axes),
223        XMin(xmin),
224        XMax(xmax),
225        YMin(ymin),
226        YMax(ymax),
227        ZMin(zmin),
228        ZMax(zmax),
229        Z2Min(z2min),
230        Z2Max(z2max),
231        X2Min(x2min),
232        X2Max(x2max)
233 {
234   for (Standard_Integer i = 0; i < NBFACES; i++) { myInfinite[i]=Standard_False; }
235   if ( ( XMax-XMin <= Precision::Confusion() ) ||
236        ( YMax-YMin <= Precision::Confusion() ) ||
237        ( ZMax-ZMin <= Precision::Confusion() ) ||
238        ( Z2Max-Z2Min < 0 ) ||
239        ( X2Max-X2Min < 0 ) )
240     Standard_DomainError::Raise();
241   Primitives_Wedge_Init(ShellBuilt,VerticesBuilt,EdgesBuilt,
242                         WiresBuilt,FacesBuilt);
243 }
244
245 //=======================================================================
246 //function : Axes,
247 //           GetXMin, GetYMin, GetZMin, GetZ2Min, GetX2Min
248 //           GetXMax, GetYMax, GetZMax, GetZ2Max, GetX2Max
249 //purpose  : trivial
250 //=======================================================================
251
252 gp_Ax2 Primitives_Wedge::Axes     () const { return myAxes; }
253 Standard_Real   Primitives_Wedge::GetXMin  () const { return XMin;   }
254 Standard_Real   Primitives_Wedge::GetYMin  () const { return YMin;   }
255 Standard_Real   Primitives_Wedge::GetZMin  () const { return ZMin;   }
256 Standard_Real   Primitives_Wedge::GetZ2Min () const { return Z2Min;  }
257 Standard_Real   Primitives_Wedge::GetX2Min () const { return X2Min;  }
258 Standard_Real   Primitives_Wedge::GetXMax  () const { return XMax;   }
259 Standard_Real   Primitives_Wedge::GetYMax  () const { return YMax;   }
260 Standard_Real   Primitives_Wedge::GetZMax  () const { return ZMax;   }
261 Standard_Real   Primitives_Wedge::GetZ2Max () const { return Z2Max;  }
262 Standard_Real   Primitives_Wedge::GetX2Max () const { return X2Max;  }
263
264 //=======================================================================
265 //function : Open
266 //purpose  : trivial
267 //=======================================================================
268
269 void Primitives_Wedge::Open (const Primitives_Direction d1)
270 {
271   Primitives_Wedge_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
272   myInfinite[Primitives_Wedge_NumDir1(d1)] = Standard_True;
273 }
274
275 //=======================================================================
276 //function : Close
277 //purpose  : trivial
278 //=======================================================================
279
280 void Primitives_Wedge::Close (const Primitives_Direction d1)
281 {
282   Primitives_Wedge_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
283   myInfinite[Primitives_Wedge_NumDir1(d1)] = Standard_False;
284 }
285
286 //=======================================================================
287 //function : IsInfinite
288 //purpose  : true if it is open in the given direction
289 //=======================================================================
290
291 Standard_Boolean Primitives_Wedge::IsInfinite (const Primitives_Direction d1) const
292 { return myInfinite[Primitives_Wedge_NumDir1(d1)]; }
293
294 //=======================================================================
295 //function : Shell
296 //purpose  : 
297 //=======================================================================
298
299 const TheShell& Primitives_Wedge::Shell() {
300   if (!ShellBuilt) {
301     myBuilder.MakeShell(myShell);
302
303     if (HasFace(Primitives_XMin))
304       myBuilder.AddShellFace(myShell,Face(Primitives_XMin));
305     if (HasFace(Primitives_XMax))
306       myBuilder.AddShellFace(myShell,Face(Primitives_XMax));
307     if (HasFace(Primitives_YMin))
308       myBuilder.AddShellFace(myShell,Face(Primitives_YMin));
309     if (HasFace(Primitives_YMax))
310       myBuilder.AddShellFace(myShell,Face(Primitives_YMax));
311     if (HasFace(Primitives_ZMin))
312       myBuilder.AddShellFace(myShell,Face(Primitives_ZMin));
313     if (HasFace(Primitives_ZMax))
314       myBuilder.AddShellFace(myShell,Face(Primitives_ZMax));
315
316     myBuilder.CompleteShell(myShell);
317     ShellBuilt = Standard_True;
318   }
319   return myShell;
320 }
321
322 //=======================================================================
323 //function : HasFace 
324 //purpose  : true if the face exist in one direction
325 //=======================================================================
326
327 Standard_Boolean Primitives_Wedge::HasFace (const Primitives_Direction d1) const
328
329   Standard_Boolean state = !myInfinite[Primitives_Wedge_NumDir1(d1)]; 
330   if ( d1 == Primitives_YMax ) state = state && ( Z2Max != Z2Min )
331                                              && ( X2Max != X2Min );
332   return state;
333 }
334
335 //=======================================================================
336 //function : Plane
337 //purpose  : 
338 //=======================================================================
339
340 gp_Pln Primitives_Wedge::Plane(const Primitives_Direction d1)
341 {
342
343   Standard_Integer i = Primitives_Wedge_NumDir1(d1);
344
345   gp_Dir D;
346   gp_Vec VX = myAxes.XDirection();
347   gp_Vec VY = myAxes.YDirection();
348   gp_Vec VZ = myAxes.Direction();
349   
350   switch (i/2) {
351     
352   case 0 :
353     D = myAxes.XDirection();
354     break;
355     
356   case 1 :
357     D = myAxes.YDirection();
358     break;
359     
360   case 2 :
361     D = myAxes.Direction();
362     break;
363     
364   };
365   Standard_Real X = 0., Y = 0., Z = 0.;
366   
367   switch (i) {
368     
369   case 0 :
370     // XMin
371     X = XMin;
372     Y = YMin;
373     Z = ZMin;
374     if ( X2Min != XMin ) D = gp_Dir((YMax-YMin)*VX+(XMin-X2Min)*VY);
375     break;
376     
377   case 1 :
378     // XMax
379     X = XMax;
380     Y = YMin;
381     Z = ZMin;
382     if ( X2Max != XMax )  D = gp_Dir((YMax-YMin)*VX+(XMax-X2Max)*VY);
383     break;
384     
385   case 2 :
386     // YMin
387     X = XMin;
388     Y = YMin;
389     Z = ZMin;
390     break;
391     
392   case 3 :
393     // YMax
394     X = XMin;
395     Y = YMax;
396     Z = ZMin;
397     break;
398     
399   case 4 :
400     // ZMin
401     X = XMin;
402     Y = YMin;
403     Z = ZMin;
404     if ( Z2Min != ZMin ) D = gp_Dir((YMax-YMin)*VZ+(ZMin-Z2Min)*VY);
405     break;
406     
407   case 5 :
408     // ZMax
409     X = XMin;
410     Y = YMin;
411     Z = ZMax;
412     if ( Z2Max != ZMax )  D = gp_Dir((YMax-YMin)*VZ+(ZMax-Z2Max)*VY);
413     break;
414     
415   };
416   
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 ()));
421   gp_Pln plane(P,D);
422   return plane;
423 }
424
425 //=======================================================================
426 //function : Face
427 //purpose  : the face in one direction
428 //=======================================================================
429
430 const TheFace& Primitives_Wedge::Face 
431        (const Primitives_Direction d1)
432 {
433
434   Standard_Integer i = Primitives_Wedge_NumDir1(d1);
435
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]);
441
442     // pcurves
443
444     Primitives_Direction dd1 = Primitives_ZMin, dd2 = Primitives_YMax, 
445     dd3 = Primitives_ZMax,dd4 = Primitives_YMin;
446
447     switch (i/2) {
448       
449     case 0 :
450       // XMin XMax
451       dd1 = Primitives_ZMin;
452       dd2 = Primitives_YMax;
453       dd3 = Primitives_ZMax;
454       dd4 = Primitives_YMin;
455       break;
456       
457     case 1 :
458       // YMin YMax
459       dd1 = Primitives_XMin;
460       dd2 = Primitives_ZMax;
461       dd3 = Primitives_XMax;
462       dd4 = Primitives_ZMin;
463       break;
464       
465     case 2 :
466       // ZMin ZMax
467       dd1 = Primitives_YMin;
468       dd2 = Primitives_XMax;
469       dd3 = Primitives_YMax;
470       dd4 = Primitives_XMin;
471       break;
472       
473     };
474
475     gp_Lin L;
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)) {
480       L = Line(d1,dd4);
481     ElSLib::Parameters(P,L.Location(),U,V);
482       DU = L.Direction() * DX;
483       DV = L.Direction() * DY;
484       myBuilder.SetPCurve(myEdges[Primitives_Wedge_NumDir2(d1,dd4)],
485                           myFaces[i],
486                           gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
487     }
488     if (HasEdge(d1,dd3)) {
489       L = Line(d1,dd3);
490     ElSLib::Parameters(P,L.Location(),U,V);
491       DU = L.Direction() * DX;
492       DV = L.Direction() * DY;
493       myBuilder.SetPCurve(myEdges[Primitives_Wedge_NumDir2(d1,dd3)],
494                           myFaces[i],
495                           gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
496     }
497
498     if (HasEdge(d1,dd2)) {
499       L = Line(d1,dd2);
500     ElSLib::Parameters(P,L.Location(),U,V);
501       DU = L.Direction() * DX;
502       DV = L.Direction() * DY;
503       myBuilder.SetPCurve(myEdges[Primitives_Wedge_NumDir2(d1,dd2)],
504                           myFaces[i],
505                           gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
506     }
507
508     if (HasEdge(d1,dd1)) {
509       L = Line(d1,dd1);
510     ElSLib::Parameters(P,L.Location(),U,V);
511       DU = L.Direction() * DX;
512       DV = L.Direction() * DY;
513       myBuilder.SetPCurve(myEdges[Primitives_Wedge_NumDir2(d1,dd1)],
514                           myFaces[i],
515                           gp_Lin2d(gp_Pnt2d(U,V),gp_Dir2d(DU,DV)));
516     }
517
518    
519     myBuilder.CompleteFace(myFaces[i]);
520     FacesBuilt[i] = Standard_True;
521   }
522   
523   return myFaces[i];
524   
525 }
526
527 //=======================================================================
528 //function : HasWire
529 //purpose  : trivial
530 //=======================================================================
531
532 Standard_Boolean Primitives_Wedge::HasWire (const Primitives_Direction d1) const
533 {
534   Standard_Integer i = Primitives_Wedge_NumDir1(d1);
535
536   if (myInfinite[i]) return Standard_False;
537   Primitives_Direction dd1 = Primitives_XMin,dd2 = Primitives_YMax,dd3 = Primitives_XMax ,dd4 = Primitives_ZMin;
538
539   switch (i/2) {
540     
541   case 0 :
542     // XMin XMax
543     dd1 = Primitives_ZMin;
544     dd2 = Primitives_YMax;
545     dd3 = Primitives_ZMax;
546     dd4 = Primitives_YMin;
547     break;
548     
549   case 1 :
550     // YMin YMax
551     dd1 = Primitives_XMin;
552     dd2 = Primitives_ZMax;
553     dd3 = Primitives_XMax;
554     dd4 = Primitives_ZMin;
555     break;
556     
557   case 2 :
558     // ZMin ZMax
559     dd1 = Primitives_YMin;
560     dd2 = Primitives_XMax;
561     dd3 = Primitives_YMax;
562     dd4 = Primitives_XMin;
563     break;
564 #ifndef DEB
565   default:
566     break;
567 #endif
568   };
569
570   return HasEdge(d1,dd1)||HasEdge(d1,dd2)||HasEdge(d1,dd3)||HasEdge(d1,dd4);
571
572 }
573
574 //=======================================================================
575 //function : Wire
576 //purpose  : trivial
577 //=======================================================================
578
579 const TheWire& Primitives_Wedge::Wire
580        (const Primitives_Direction d1)
581 {
582   Standard_Integer i = Primitives_Wedge_NumDir1(d1);
583
584   Primitives_Direction dd1 = Primitives_XMin,dd2 = Primitives_YMax,dd3 = Primitives_XMax ,dd4 = Primitives_ZMin;
585
586   if (!WiresBuilt[i]) {
587
588     switch (i/2) {
589       
590     case 0 :
591       // XMin XMax
592       dd1 = Primitives_ZMin;
593       dd2 = Primitives_YMax;
594       dd3 = Primitives_ZMax;
595       dd4 = Primitives_YMin;
596       break;
597       
598     case 1 :
599       // YMin YMax
600       dd1 = Primitives_XMin;
601       dd2 = Primitives_ZMax;
602       dd3 = Primitives_XMax;
603       dd4 = Primitives_ZMin;
604       break;
605       
606     case 2 :
607       // ZMin ZMax
608       dd1 = Primitives_YMin;
609       dd2 = Primitives_XMax;
610       dd3 = Primitives_YMax;
611       dd4 = Primitives_XMin;
612       break;
613 #ifndef DEB
614     default:
615       break;
616 #endif
617     };
618
619     myBuilder.MakeWire(myWires[i]);
620   
621     if (HasEdge(d1,dd4))
622       myBuilder.AddWireEdge(myWires[i],Edge(d1,dd4),Standard_False);
623     if (HasEdge(d1,dd3))
624       myBuilder.AddWireEdge(myWires[i],Edge(d1,dd3),Standard_False);
625     if (HasEdge(d1,dd2))
626       myBuilder.AddWireEdge(myWires[i],Edge(d1,dd2),Standard_True );
627     if (HasEdge(d1,dd1))
628       myBuilder.AddWireEdge(myWires[i],Edge(d1,dd1),Standard_True );
629    
630     myBuilder.CompleteWire(myWires[i]);
631     WiresBuilt[i] = Standard_True;
632   }
633    
634   return myWires[i];
635
636 }
637
638 //=======================================================================
639 //function : HasEdge
640 //purpose  : trivial
641 //=======================================================================
642
643 Standard_Boolean Primitives_Wedge::HasEdge (const Primitives_Direction d1,
644                                    const Primitives_Direction d2) const
645
646   Standard_Boolean state = !(myInfinite[Primitives_Wedge_NumDir1(d1)] ||
647                     myInfinite[Primitives_Wedge_NumDir1(d2)]); 
648   Standard_Integer i = Primitives_Wedge_NumDir2(d1,d2);
649   if      ( i == 6 || i == 7 ) state = state && ( X2Max != X2Min );
650   else if ( i == 1 || i == 3 ) state = state && ( Z2Max != Z2Min );
651   return state;
652 }
653
654 //=======================================================================
655 //function : Line
656 //purpose  : trivial
657 //=======================================================================
658
659 gp_Lin Primitives_Wedge::Line
660   (const Primitives_Direction d1,
661    const Primitives_Direction d2)
662 {
663   if (!HasEdge(d1,d2)) Standard_DomainError::Raise();
664
665   Standard_Integer i = Primitives_Wedge_NumDir2(d1,d2);
666
667   Standard_Real X =0., Y =0., Z =0.;
668
669   gp_Dir D;
670   gp_Vec VX = myAxes.XDirection();
671   gp_Vec VY = myAxes.YDirection();
672   gp_Vec VZ = myAxes.Direction();
673   Primitives_Direction dd1,dd2;
674   
675   switch (i/4) {
676     
677   case 0 :
678     D = myAxes.Direction();
679     dd1 = Primitives_ZMin;
680     dd2 = Primitives_ZMax;
681     break;
682     
683   case 1 :
684     D = myAxes.XDirection();
685     dd1 = Primitives_XMin;
686     dd2 = Primitives_XMax;
687     break;
688     
689   case 2 :
690     D = myAxes.YDirection();
691     dd1 = Primitives_YMin;
692     dd2 = Primitives_YMax;
693     break;
694     
695   };
696   
697   switch (i) {
698     
699   case 0 :
700     // XMin YMin
701     X = XMin;
702     Y = YMin;
703     Z = ZMin;
704     break;
705       
706   case 1 :
707     // XMin YMax
708     X = X2Min;
709     Y = YMax;
710     Z = Z2Min;
711     break;
712       
713   case 2 :
714     // XMax YMin
715     X = XMax;
716     Y = YMin;
717     Z = ZMin;
718     break;
719     
720   case 3 :
721     // XMax YMax
722     X = X2Max;
723     Y = YMax;
724     Z = Z2Min;
725     break;
726     
727   case 4 :
728     // YMin ZMin
729     X = XMin;
730     Y = YMin;
731     Z = ZMin;
732     break;
733     
734   case 5 :
735     // YMin ZMax
736     X = XMin;
737     Y = YMin;
738     Z = ZMax;
739     break;
740       
741   case 6 :
742     // YMax ZMin
743     X = X2Min;
744     Y = YMax;
745     Z = Z2Min;
746     break;
747       
748   case 7 :
749     // YMax ZMax
750     X = X2Min;
751     Y = YMax;
752     Z = Z2Max;
753     break;
754       
755   case 8 :
756     // ZMin XMin
757     X = XMin;
758     Y = YMin;
759     Z = ZMin;
760     if ( (XMin != X2Min) || (ZMin != Z2Min) ) 
761       D = gp_Vec( (X2Min-XMin)*VX + (YMax-YMin)*VY + (Z2Min-ZMin)*VZ);
762     break;
763     
764   case 9 :
765     // ZMax XMin
766     X = XMin;
767     Y = YMin;
768     Z = ZMax;
769     if ( (XMin != X2Min) || (ZMax != Z2Max) ) 
770       D = gp_Vec( (X2Min-XMin)*VX + (YMax-YMin)*VY + (Z2Max-ZMax)*VZ);
771     break;
772     
773   case 10 :
774     // ZMin XMax
775     X = XMax;
776     Y = YMin;
777     Z = ZMin;
778     if ( (XMax != X2Max) || (ZMin != Z2Min) ) 
779       D = gp_Vec( (X2Max-XMax)*VX + (YMax-YMin)*VY + (Z2Min-ZMin)*VZ);
780     break;
781     
782   case 11 :
783     // ZMax XMax
784     X = XMax;
785     Y = YMin;
786     Z = ZMax;
787     if ( (XMax != X2Max) || (ZMax != Z2Max) ) 
788       D = gp_Vec(gp_Pnt(XMax,YMin,ZMax),gp_Pnt(X2Max,YMax,Z2Max));
789       D = gp_Vec( (X2Max-XMax)*VX + (YMax-YMin)*VY + (Z2Max-ZMax)*VZ);
790     break;
791       
792   }
793
794   gp_Pnt P = myAxes.Location();
795   P.Translate(X*gp_Vec(myAxes.XDirection()));
796   P.Translate(Y*gp_Vec(myAxes.YDirection()));
797   P.Translate(Z*gp_Vec(myAxes.Direction ()));
798   return gp_Lin(gp_Ax1(P,D));
799     
800 }
801
802 //=======================================================================
803 //function : Edge
804 //purpose  : trivial
805 //=======================================================================
806
807 const TheEdge& Primitives_Wedge::Edge
808        (const Primitives_Direction d1,
809         const Primitives_Direction d2)
810 {
811   if (!HasEdge(d1,d2)) Standard_DomainError::Raise();
812
813   Standard_Integer i = Primitives_Wedge_NumDir2(d1,d2);
814
815   if (!EdgesBuilt[i]) {
816
817     Primitives_Direction dd1 = Primitives_XMin ,dd2 = Primitives_XMax;
818
819     switch (i/4) {
820     
821     case 0 :
822       dd1 = Primitives_ZMin;
823       dd2 = Primitives_ZMax;
824       break;
825     
826     case 1 :
827       dd1 = Primitives_XMin;
828       dd2 = Primitives_XMax;
829       break;
830     
831     case 2 :
832       dd1 = Primitives_YMin;
833       dd2 = Primitives_YMax;
834       break;
835 #ifndef DEB
836     default:
837       break;
838 #endif
839     };
840     
841     gp_Lin L = Line(d1,d2);
842     myBuilder.MakeEdge(myEdges[i],L);
843     
844     if (HasVertex(d1,d2,dd2)) {
845       myBuilder.AddEdgeVertex(myEdges[i],Vertex(d1,d2,dd2),
846                               ElCLib::Parameter(L,Point(d1,d2,dd2)),
847                               Standard_False);
848     }
849     if (HasVertex(d1,d2,dd1)) {
850       myBuilder.AddEdgeVertex(myEdges[i],Vertex(d1,d2,dd1),
851                               ElCLib::Parameter(L,Point(d1,d2,dd1)),
852                               Standard_True );
853     }
854     
855     if ( Z2Max == Z2Min ) {
856       if ( i == 6 ) {
857         myEdges[7]    = myEdges[6];
858         EdgesBuilt[7] = Standard_True;
859       }
860       else if ( i == 7 ) {
861         myEdges[6]    = myEdges[7];
862         EdgesBuilt[6] = Standard_True;
863       }
864     }
865     if ( X2Max == X2Min ) {
866       if ( i == 1 ) {
867         myEdges[3]    = myEdges[1];
868         EdgesBuilt[3] = Standard_True;
869       }
870       else if ( i == 3 ) {
871         myEdges[1]    = myEdges[3];
872         EdgesBuilt[1] = Standard_True;
873       }
874     }
875
876     myBuilder.CompleteEdge(myEdges[i]);
877     EdgesBuilt[i] = Standard_True;
878   }
879
880   return myEdges[i];
881
882 }
883
884 //=======================================================================
885 //function : HasVertex
886 //purpose  : trivial
887 //=======================================================================
888
889 Standard_Boolean Primitives_Wedge::HasVertex
890   (const Primitives_Direction d1,
891    const Primitives_Direction d2,
892    const Primitives_Direction d3) const
893 { return !(myInfinite[Primitives_Wedge_NumDir1(d1)] ||
894            myInfinite[Primitives_Wedge_NumDir1(d2)] ||
895            myInfinite[Primitives_Wedge_NumDir1(d3)]); }
896
897 //=======================================================================
898 //function : Point
899 //purpose  : trivial
900 //=======================================================================
901
902 gp_Pnt  Primitives_Wedge::Point
903   (const Primitives_Direction d1,
904    const Primitives_Direction d2,
905    const Primitives_Direction d3)
906 {
907   if (!HasVertex(d1,d2,d3)) Standard_DomainError::Raise();
908
909   Standard_Integer i = Primitives_Wedge_NumDir3(d1,d2,d3);
910
911   Standard_Real X =0., Y =0., Z =0.;
912
913   switch (i) {
914     
915   case 0 :
916     X = XMin;
917     Y = YMin;
918     Z = ZMin;
919     break;
920     
921   case 1 :
922     X = XMin;
923     Y = YMin;
924     Z = ZMax;
925     break;
926     
927   case 2 :
928     X = X2Min;
929     Y = YMax;
930     Z = Z2Min;
931     break;
932     
933   case 3 :
934     X = X2Min;
935     Y = YMax;
936     Z = Z2Max;
937     break;
938     
939   case 4 :
940     X = XMax;
941     Y = YMin;
942     Z = ZMin;
943     break;
944     
945   case 5 :
946     X = XMax;
947     Y = YMin;
948     Z = ZMax;
949     break;
950     
951   case 6 :
952     X = X2Max;
953     Y = YMax;
954     Z = Z2Min;
955     break;
956
957   case 7 :
958     X = X2Max;
959     Y = YMax;
960     Z = Z2Max;
961     break;
962     
963   };
964
965   gp_Pnt P = myAxes.Location();
966   P.Translate(X*gp_Vec(myAxes.XDirection()));
967   P.Translate(Y*gp_Vec(myAxes.YDirection()));
968   P.Translate(Z*gp_Vec(myAxes.Direction ()));
969   return P;
970 }
971
972 //=======================================================================
973 //function : Vertex
974 //purpose  : trivial
975 //=======================================================================
976
977 const TheVertex& Primitives_Wedge::Vertex 
978        (const Primitives_Direction d1,
979         const Primitives_Direction d2,
980         const Primitives_Direction d3)
981 {
982   if (!HasVertex(d1,d2,d3)) Standard_DomainError::Raise();
983
984   Standard_Integer i = Primitives_Wedge_NumDir3(d1,d2,d3);
985
986   if (!VerticesBuilt[i]) {
987
988     myBuilder.MakeVertex(myVertices[i],Point(d1,d2,d3));
989
990     if ( Z2Max == Z2Min ) {
991       if      ( i == 2 || i == 6 ) {
992         myVertices[3] = myVertices[2];
993         myVertices[7] = myVertices[6];
994         VerticesBuilt[3] = Standard_True;
995         VerticesBuilt[7] = Standard_True;
996       }
997       else if ( i == 3 || i == 7 ) {
998         myVertices[2] = myVertices[3];
999         myVertices[6] = myVertices[7];
1000         VerticesBuilt[2] = Standard_True;
1001         VerticesBuilt[6] = Standard_True;
1002       }
1003     }
1004     if ( X2Max == X2Min ) {
1005       if      ( i == 2 || i == 3 ) {
1006         myVertices[6] = myVertices[2];
1007         myVertices[7] = myVertices[3];
1008         VerticesBuilt[6] = Standard_True;
1009         VerticesBuilt[7] = Standard_True;
1010       }
1011       else if ( i == 6 || i == 7 ) {
1012         myVertices[2] = myVertices[6];
1013         myVertices[3] = myVertices[7];
1014         VerticesBuilt[2] = Standard_True;
1015         VerticesBuilt[3] = Standard_True;
1016       }
1017     }
1018
1019     VerticesBuilt[i] = Standard_True;
1020   }
1021
1022   return myVertices[i];
1023
1024 }
1025