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