1 // Created on: 2008-03-20
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2008-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <NIS_Surface.hxx>
17 #include <NIS_SurfaceDrawer.hxx>
18 #include <NIS_Triangulated.hxx>
19 #include <BRepMesh_IncrementalMesh.hxx>
20 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
21 #include <BRep_PolygonOnTriangulation.hxx>
22 #include <BRep_TEdge.hxx>
23 #include <BRep_Tool.hxx>
24 #include <Geom_Surface.hxx>
25 #include <NCollection_Map.hxx>
26 #include <Poly_PolygonOnTriangulation.hxx>
27 #include <Poly_Triangulation.hxx>
28 #include <Precision.hxx>
29 #include <TColgp_Array1OfPnt2d.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopLoc_Location.hxx>
33 #include <TopTools_MapOfShape.hxx>
35 #include <TopoDS_Face.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TShort_Array1OfShortReal.hxx>
40 IMPLEMENT_STANDARD_HANDLE (NIS_Surface, NIS_InteractiveObject)
41 IMPLEMENT_STANDARD_RTTIEXT(NIS_Surface, NIS_InteractiveObject)
43 //=======================================================================
45 //purpose : Compare two triangulations, for NCollection_Map interface.
46 //=======================================================================
48 inline Standard_Boolean IsEqual(const Handle(Poly_Triangulation)& theT0,
49 const Handle(Poly_Triangulation)& theT1)
51 return (theT0 == theT1);
54 //=======================================================================
55 //function : NIS_Surface
57 //=======================================================================
59 NIS_Surface::NIS_Surface(const Handle(NCollection_BaseAllocator)& theAlloc)
71 myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
74 //=======================================================================
75 //function : NIS_Surface
77 //=======================================================================
79 NIS_Surface::NIS_Surface (const Handle(Poly_Triangulation)& theTri,
80 const Handle(NCollection_BaseAllocator)& theAlloc)
91 myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
92 if (theTri.IsNull() == Standard_False)
94 // Alocate arrays of entities
95 myNNodes = 3 * theTri->NbTriangles();
96 myNTriangles = theTri->NbTriangles();
97 mypNodes = static_cast<Standard_ShortReal*>
98 (myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
99 mypNormals = static_cast<Standard_ShortReal *>
100 (myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
101 mypTriangles = static_cast<Standard_Integer*>
102 (myAlloc->Allocate(sizeof(Standard_Integer) * 3 * myNTriangles));
104 // Copy the data from the original triangulation.
105 Standard_Integer i, iN(0), iT(0);
106 const Poly_Array1OfTriangle& arrTri = theTri->Triangles();
107 const TColgp_Array1OfPnt& arrNodes = theTri->Nodes();
108 for (i = arrTri.Lower(); i <= arrTri.Upper(); i++) {
109 Standard_Integer iNode[3];
110 arrTri(i).Get(iNode[0], iNode[1], iNode[2]);
111 gp_XYZ aNorm = ((arrNodes(iNode[1]).XYZ() - arrNodes(iNode[0]).XYZ()) ^
112 (arrNodes(iNode[2]).XYZ() - arrNodes(iNode[0]).XYZ()));
113 const Standard_Real aMagn = aNorm.Modulus();
114 if (aMagn > Precision::Confusion())
117 aNorm.SetCoord(0., 0., 1.);
118 mypNodes[iN+0] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).X());
119 mypNodes[iN+1] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).Y());
120 mypNodes[iN+2] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).Z());
121 mypNodes[iN+3] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).X());
122 mypNodes[iN+4] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).Y());
123 mypNodes[iN+5] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).Z());
124 mypNodes[iN+6] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).X());
125 mypNodes[iN+7] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).Y());
126 mypNodes[iN+8] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).Z());
127 mypNormals[iN+0] = static_cast<Standard_ShortReal>(aNorm.X());
128 mypNormals[iN+1] = static_cast<Standard_ShortReal>(aNorm.Y());
129 mypNormals[iN+2] = static_cast<Standard_ShortReal>(aNorm.Z());
130 mypNormals[iN+3] = static_cast<Standard_ShortReal>(aNorm.X());
131 mypNormals[iN+4] = static_cast<Standard_ShortReal>(aNorm.Y());
132 mypNormals[iN+5] = static_cast<Standard_ShortReal>(aNorm.Z());
133 mypNormals[iN+6] = static_cast<Standard_ShortReal>(aNorm.X());
134 mypNormals[iN+7] = static_cast<Standard_ShortReal>(aNorm.Y());
135 mypNormals[iN+8] = static_cast<Standard_ShortReal>(aNorm.Z());
136 mypTriangles[iT+0] = iT+0;
137 mypTriangles[iT+1] = iT+1;
138 mypTriangles[iT+2] = iT+2;
145 //=======================================================================
146 //function : NIS_Surface
147 //purpose : Constructor
148 //=======================================================================
150 NIS_Surface::NIS_Surface (const TopoDS_Shape& theShape,
151 const Standard_Real theDeflection,
152 const Handle(NCollection_BaseAllocator)& theAlloc)
153 : myAlloc (theAlloc),
163 if (myAlloc.IsNull())
164 myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
165 Init (theShape, theDeflection);
168 //=======================================================================
170 //purpose : Initialize the instance with a TopoDS_Shape.
171 //=======================================================================
173 void NIS_Surface::Init (const TopoDS_Shape& theShape,
174 const Standard_Real theDeflection)
176 TopLoc_Location aLoc, aLocSurf;
178 // Count the nodes and triangles in faces
179 NCollection_Map<Handle(Poly_Triangulation)> mapTri;
180 TopExp_Explorer fexp (theShape, TopAbs_FACE);
181 for (; fexp.More(); fexp.Next())
183 const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
185 const Handle(Poly_Triangulation)& aTriangulation
186 = BRep_Tool::Triangulation (aFace, aLoc);
188 if (aTriangulation.IsNull())
189 BRepMesh_IncrementalMesh aMeshTool(aFace, theDeflection);
191 if (aTriangulation.IsNull() == Standard_False)
193 myNNodes += aTriangulation->NbNodes();
194 myNTriangles += aTriangulation->NbTriangles();
195 mapTri.Add(aTriangulation);
199 // Create map of edges, to build wireframe for all edges.
200 TopTools_MapOfShape mapEdges;
201 TopExp_Explorer eexp (theShape, TopAbs_EDGE);
202 for (; eexp.More(); eexp.Next())
204 const TopoDS_Shape& anEdge = eexp.Current();
205 mapEdges.Add(anEdge);
208 // Allocate arrays of entities
209 if (myNNodes && myNTriangles) {
210 mypNodes = static_cast<Standard_ShortReal *>
211 (myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
212 mypNormals = static_cast<Standard_ShortReal *>
213 (myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
214 mypTriangles = static_cast<Standard_Integer *>
215 (myAlloc->Allocate(sizeof(Standard_Integer) * 3 * myNTriangles));
216 mypEdges = static_cast<Standard_Integer **>
217 (myAlloc->Allocate(sizeof(Standard_Integer *) * mapEdges.Extent()));
220 // The second loop: copy all nodes and triangles face-by-face
221 const Standard_Real eps2 = Precision::SquareConfusion();
222 Standard_Integer nNodes (0), nTriangles (0);
223 for (fexp.ReInit(); fexp.More(); fexp.Next())
225 const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
226 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLocSurf);
227 const Handle(Poly_Triangulation)& aTriangulation =
228 BRep_Tool::Triangulation(aFace, aLoc);
229 if (aTriangulation.IsNull() == Standard_False)
231 // Prepare transformation
232 Standard_Integer i, aNodeInd(nNodes)/*, aNTriangles = 0*/;
233 const gp_Trsf& aTrf = aLoc.Transformation();
234 const gp_Trsf& aTrfSurf = aLocSurf.Transformation();
235 Standard_Boolean isReverse = (aFace.Orientation() == TopAbs_REVERSED);
237 // Store all nodes of the current face in the data model
238 const TColgp_Array1OfPnt& tabNode = aTriangulation->Nodes();
239 const TColgp_Array1OfPnt2d& tabUV = aTriangulation->UVNodes();
240 for (i = tabNode.Lower(); i <= tabNode.Upper(); i++)
243 tabNode(i).Transformed(aTrf).Coord (t[0], t[1], t[2]);
244 // write node to mesh data
245 mypNodes[3*aNodeInd + 0] = static_cast<Standard_ShortReal>(t[0]);
246 mypNodes[3*aNodeInd + 1] = static_cast<Standard_ShortReal>(t[1]);
247 mypNodes[3*aNodeInd + 2] = static_cast<Standard_ShortReal>(t[2]);
251 gp_XYZ aNorm(0., 0., 0.);
253 if (aTriangulation->HasNormals()) {
254 // Retrieve the normal direction from the triangulation
255 aNorm.SetCoord(aTriangulation->Normals().Value(3*i-2),
256 aTriangulation->Normals().Value(3*i-1),
257 aTriangulation->Normals().Value(3*i-0));
258 } else if (aSurf.IsNull() == Standard_False)
260 // Compute the surface normal at the Node.
261 aSurf->D1(tabUV(i).X(), tabUV(i).Y(), aP, aD1U, aD1V);
262 aNorm = (aD1U.Crossed(aD1V)).XYZ();
267 const Standard_Real aMod = aNorm.SquareModulus();
269 gp_Dir aDirNorm(aNorm);
270 aDirNorm.Transform(aTrfSurf);
271 aDirNorm.Coord (t[0], t[1], t[2]);
277 mypNormals[3*aNodeInd + 0] = static_cast<Standard_ShortReal>(t[0]);
278 mypNormals[3*aNodeInd + 1] = static_cast<Standard_ShortReal>(t[1]);
279 mypNormals[3*aNodeInd + 2] = static_cast<Standard_ShortReal>(t[2]);
283 const Standard_Integer nNodes1 = nNodes - 1;
284 // Store all triangles of the current face in the data model
285 const Poly_Array1OfTriangle& tabTri = aTriangulation->Triangles();
286 for (i = tabTri.Lower(); i <= tabTri.Upper(); i++)
288 Standard_Integer aN[3];
289 tabTri(i).Get (aN[0], aN[1], aN[2]);
290 Standard_Integer * pTriangle = &mypTriangles[nTriangles*3];
291 pTriangle[0] = aN[0] + nNodes1;
293 pTriangle[1] = aN[2] + nNodes1;
294 pTriangle[2] = aN[1] + nNodes1;
296 pTriangle[1] = aN[1] + nNodes1;
297 pTriangle[2] = aN[2] + nNodes1;
299 const Standard_ShortReal aVec0[3] = {
300 mypNodes[3*pTriangle[1]+0] - mypNodes[3*pTriangle[0]+0],
301 mypNodes[3*pTriangle[1]+1] - mypNodes[3*pTriangle[0]+1],
302 mypNodes[3*pTriangle[1]+2] - mypNodes[3*pTriangle[0]+2]
304 const Standard_ShortReal aVec1[3] = {
305 mypNodes[3*pTriangle[2]+0] - mypNodes[3*pTriangle[0]+0],
306 mypNodes[3*pTriangle[2]+1] - mypNodes[3*pTriangle[0]+1],
307 mypNodes[3*pTriangle[2]+2] - mypNodes[3*pTriangle[0]+2]
309 const Standard_ShortReal aVecP[3] = {
310 aVec0[1] * aVec1[2] - aVec0[2] * aVec1[1],
311 aVec0[2] * aVec1[0] - aVec0[0] * aVec1[2],
312 aVec0[0] * aVec1[1] - aVec0[1] * aVec1[0]
314 if (aVecP[0]*aVecP[0] + aVecP[1]*aVecP[1] + aVecP[2]*aVecP[2] > eps2)
317 // Store all edge polygons on the current face.
318 for (eexp.Init(aFace, TopAbs_EDGE); eexp.More(); eexp.Next())
320 const TopoDS_Edge& anEdge = TopoDS::Edge(eexp.Current());
321 if (mapEdges.Remove(anEdge)) {
322 const Handle(Poly_PolygonOnTriangulation)& aPolygon =
323 BRep_Tool::PolygonOnTriangulation(anEdge, aTriangulation, aLoc);
324 if (aPolygon.IsNull() == Standard_False) {
325 const TColStd_Array1OfInteger& arrNode = aPolygon->Nodes();
326 // Allocate memory to store the current polygon indices.
327 Standard_Integer aLen = arrNode.Length();
328 Standard_Integer * pEdge = static_cast<Standard_Integer *>
329 (myAlloc->Allocate(sizeof(Standard_Integer) * (aLen + 1)));
330 const gp_Pnt* pLast = &tabNode(arrNode(arrNode.Lower()));
331 pEdge[1] = arrNode(arrNode.Lower()) + nNodes1;
332 Standard_Integer iPNode(arrNode.Lower() + 1), iENode(1);
333 for (; iPNode <= arrNode.Upper(); iPNode++)
335 const Standard_Integer aN(arrNode(iPNode));
336 if (pLast->SquareDistance(tabNode(aN)) < eps2)
340 pLast = &tabNode(aN);
341 pEdge[++iENode] = aN + nNodes1;
344 // Do not save very short polygons
347 mypEdges[myNEdges++] = pEdge;
352 nNodes += tabNode.Length();
355 myNTriangles = nTriangles;
357 if (GetDrawer().IsNull() == Standard_False)
361 setIsUpdateBox(Standard_True);
364 //=======================================================================
365 //function : ~NIS_Surface
366 //purpose : Destructor
367 //=======================================================================
369 NIS_Surface::~NIS_Surface ()
374 //=======================================================================
377 //=======================================================================
379 void NIS_Surface::Clear ()
383 myAlloc->Free(mypNodes);
384 myAlloc->Free(mypNormals);
388 myAlloc->Free(mypTriangles);
391 for (Standard_Integer i = 0; i < myNEdges; i++) {
392 myAlloc->Free(mypEdges[i]);
395 myAlloc->Free(mypEdges);
397 if (GetDrawer().IsNull() == Standard_False) {
398 GetDrawer()->SetUpdated(NIS_Drawer::Draw_Normal,
399 NIS_Drawer::Draw_Top,
400 NIS_Drawer::Draw_Transparent,
401 NIS_Drawer::Draw_Hilighted);
406 //=======================================================================
407 //function : DefaultDrawer
409 //=======================================================================
411 NIS_Drawer * NIS_Surface::DefaultDrawer (NIS_Drawer * theDrawer) const
413 NIS_SurfaceDrawer * aDrawer =
414 theDrawer ? static_cast<NIS_SurfaceDrawer *>(theDrawer)
415 : new NIS_SurfaceDrawer (Quantity_NOC_SLATEBLUE4);
416 aDrawer->SetBackColor (Quantity_NOC_DARKGREEN);
417 aDrawer->myIsWireframe = myIsWireframe;
421 //=======================================================================
422 //function : SetColor
423 //purpose : Set the normal color for presentation.
424 //=======================================================================
426 void NIS_Surface::SetColor (const Quantity_Color& theColor)
428 const Handle(NIS_SurfaceDrawer) aDrawer =
429 static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
430 aDrawer->Assign (GetDrawer());
431 aDrawer->myColor[NIS_Drawer::Draw_Normal] = theColor;
432 aDrawer->myColor[NIS_Drawer::Draw_Top] = theColor;
433 aDrawer->myColor[NIS_Drawer::Draw_Transparent] = theColor;
437 //=======================================================================
438 //function : SetBackColor
439 //purpose : Set the normal color for presentation of back side of triangles.
440 //=======================================================================
442 void NIS_Surface::SetBackColor (const Quantity_Color& theColor)
444 const Handle(NIS_SurfaceDrawer) aDrawer =
445 static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
446 aDrawer->Assign (GetDrawer());
447 aDrawer->myBackColor = theColor;
451 //=======================================================================
452 //function : SetPolygonOffset
454 //=======================================================================
456 void NIS_Surface::SetPolygonOffset (const Standard_Real theValue)
458 const Handle(NIS_SurfaceDrawer) aDrawer =
459 static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
460 aDrawer->Assign (GetDrawer());
461 aDrawer->myPolygonOffset = static_cast<Standard_ShortReal>(theValue);
465 //=======================================================================
466 //function : SetDisplayMode
467 //purpose : Set the display mode: Shading or Wireframe.
468 //=======================================================================
470 void NIS_Surface::SetDisplayMode (const NIS_Surface::DisplayMode theMode)
472 Standard_Boolean isUpdate(Standard_False);
474 if (theMode != Wireframe) {
475 myIsWireframe = Standard_False;
476 isUpdate = Standard_True;
479 if (theMode == Wireframe) {
480 myIsWireframe = Standard_True;
481 isUpdate = Standard_True;
484 if (isUpdate && !GetDrawer().IsNull()) {
485 const Handle(NIS_SurfaceDrawer) aDrawer =
486 static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
487 aDrawer->Assign (GetDrawer());
488 aDrawer->myIsWireframe = myIsWireframe;
493 //=======================================================================
494 //function : GetDisplayMode
495 //purpose : Query the current display mode: Shading or Wireframe.
496 //=======================================================================
498 NIS_Surface::DisplayMode NIS_Surface::GetDisplayMode () const
500 return myIsWireframe ? Wireframe : Shading;
503 //=======================================================================
506 //=======================================================================
508 void NIS_Surface::Clone (const Handle(NCollection_BaseAllocator)& theAlloc,
509 Handle(NIS_InteractiveObject)& theDest) const
511 Handle(NIS_Surface) aNewObj;
512 if (theDest.IsNull()) {
513 aNewObj = new NIS_Surface(theAlloc);
516 aNewObj = reinterpret_cast<NIS_Surface*> (theDest.operator->());
517 aNewObj->myAlloc = theAlloc;
519 NIS_InteractiveObject::Clone(theAlloc, theDest);
520 aNewObj->myNNodes = myNNodes;
522 // copy nodes and normals
523 const Standard_Size nBytes = myNNodes*3*sizeof(Standard_ShortReal);
524 aNewObj->mypNodes = (Standard_ShortReal *)theAlloc->Allocate(nBytes);
525 aNewObj->mypNormals = (Standard_ShortReal *)theAlloc->Allocate(nBytes);
526 memcpy(aNewObj->mypNodes, mypNodes, nBytes);
527 memcpy(aNewObj->mypNormals, mypNormals, nBytes);
529 aNewObj->myNTriangles = myNTriangles;
530 if (myNTriangles > 0) {
531 const Standard_Size nBytes = sizeof(Standard_Integer) * 3 * myNTriangles;
532 aNewObj->mypTriangles = (Standard_Integer *)theAlloc->Allocate(nBytes);
533 memcpy(aNewObj->mypTriangles, mypTriangles, nBytes);
535 aNewObj->myNEdges = myNEdges;
537 aNewObj->mypEdges = static_cast<Standard_Integer **>
538 (theAlloc->Allocate(sizeof(Standard_Integer *) * myNEdges));
539 for (Standard_Integer i = 0; i < myNEdges; i++) {
540 const Standard_Integer * pEdge = mypEdges[i];
541 const Standard_Size nBytes = sizeof(Standard_Integer) * (pEdge[0] + 1);
542 aNewObj->mypEdges[i] =
543 static_cast<Standard_Integer *> (theAlloc->Allocate(nBytes));
544 memcpy(aNewObj->mypEdges[i], pEdge, nBytes);
547 aNewObj->myIsWireframe = myIsWireframe;
550 //=======================================================================
551 //function : Intersect
553 //=======================================================================
555 Standard_Real NIS_Surface::Intersect (const gp_Ax1& theAxis,
556 const Standard_Real theOver) const
558 Standard_Real aResult (RealLast());
559 Standard_Real start[3], dir[3];
560 theAxis.Location().Coord(start[0], start[1], start[2]);
561 theAxis.Direction().Coord(dir[0], dir[1], dir[2]);
564 if (myIsWireframe == Standard_False)
565 for (Standard_Integer i = 0; i < myNTriangles; i++) {
566 const Standard_Integer * pTri = &mypTriangles[3*i];
567 if (NIS_Triangulated::tri_line_intersect (start, dir,
568 &mypNodes[3*pTri[0]],
569 &mypNodes[3*pTri[1]],
570 &mypNodes[3*pTri[2]],
572 if (anInter < aResult)
576 const Standard_Real anOver2 = theOver*theOver;
577 for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
578 const Standard_Integer * anEdge = mypEdges[iEdge];
579 const Standard_Integer nNodes = anEdge[0];
580 for (Standard_Integer i = 1; i < nNodes; i++) {
581 // Node index is incremented for the head of polygon indice array
582 if (NIS_Triangulated::seg_line_intersect (theAxis.Location().XYZ(),
583 theAxis.Direction().XYZ(),
585 &mypNodes[3*anEdge[i+0]],
586 &mypNodes[3*anEdge[i+1]],
588 if (anInter < aResult)
597 //=======================================================================
598 //function : Intersect
600 //=======================================================================
602 Standard_Boolean NIS_Surface::Intersect (const Bnd_B3f& theBox,
603 const gp_Trsf& theTrf,
604 const Standard_Boolean isFullIn) const
606 Standard_Boolean aResult (isFullIn);
608 if (myIsWireframe == Standard_False) {
609 if (myNTriangles > 0) {
610 for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
611 gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
612 static_cast<Standard_Real>(mypNodes[iNode+1]),
613 static_cast<Standard_Real>(mypNodes[iNode+2]));
614 theTrf.Transforms(aPnt);
615 if (theBox.IsOut (aPnt) == isFullIn) {
622 for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
623 const Standard_Integer * anEdge = mypEdges[iEdge];
624 const Standard_Integer nNodes = anEdge[0];
625 for (Standard_Integer i = 1; i < nNodes; i++) {
626 // index is incremented by 1 for the head number in the array
628 gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
629 static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
630 static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
631 gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
632 static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
633 static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
635 aPnt[0].Transform(theTrf);
636 aPnt[1].Transform(theTrf);
638 if (NIS_Triangulated::seg_box_included (theBox, aPnt) == 0) {
639 aResult = Standard_False;
643 if (NIS_Triangulated::seg_box_intersect (theBox, aPnt)) {
644 aResult = Standard_True;
654 //=======================================================================
655 //function : Intersect
656 //purpose : Selection by polygon
657 //=======================================================================
659 Standard_Boolean NIS_Surface::Intersect
660 (const NCollection_List<gp_XY> &thePolygon,
661 const gp_Trsf &theTrf,
662 const Standard_Boolean isFullIn) const
664 Standard_Boolean aResult (isFullIn);
666 if (myIsWireframe == Standard_False) {
667 if (myNTriangles > 0) {
668 for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
669 gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
670 static_cast<Standard_Real>(mypNodes[iNode+1]),
671 static_cast<Standard_Real>(mypNodes[iNode+2]));
672 theTrf.Transforms(aPnt);
673 gp_XY aP2d(aPnt.X(), aPnt.Y());
675 if (!NIS_Triangulated::IsIn(thePolygon, aP2d)) {
677 aResult = Standard_False;
681 if (isFullIn == Standard_False) {
682 aResult = Standard_True;
689 for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
690 const Standard_Integer * anEdge = mypEdges[iEdge];
691 const Standard_Integer nNodes = anEdge[0];
692 for (Standard_Integer i = 1; i < nNodes; i++) {
693 // index is incremented by 1 for the head number in the array
695 gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
696 static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
697 static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
698 gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
699 static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
700 static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
702 aPnt[0].Transform(theTrf);
703 aPnt[1].Transform(theTrf);
704 const gp_XY aP2d[2] = { gp_XY(aPnt[0].X(), aPnt[0].Y()),
705 gp_XY(aPnt[1].X(), aPnt[1].Y()) };
707 if (NIS_Triangulated::seg_polygon_included (thePolygon, aP2d) == 0) {
708 aResult = Standard_False;
712 if (NIS_Triangulated::seg_polygon_intersect (thePolygon, aP2d)) {
713 aResult = Standard_True;
723 //=======================================================================
724 //function : computeBox
726 //=======================================================================
728 void NIS_Surface::computeBox ()
730 NIS_Triangulated::ComputeBox(myBox, myNNodes, mypNodes, 3);
732 const Handle(NIS_SurfaceDrawer)& aDrawer =
733 static_cast<const Handle(NIS_SurfaceDrawer)&> (GetDrawer());
735 if (aDrawer.IsNull() == Standard_False) {
736 const gp_Trsf& aTrsf = aDrawer->GetTransformation();
737 myBox = myBox.Transformed(aTrsf);