1 // Created on: 2008-03-20
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2008-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #include <NIS_Surface.hxx>
22 #include <NIS_SurfaceDrawer.hxx>
23 #include <NIS_Triangulated.hxx>
24 #include <BRepMesh_IncrementalMesh.hxx>
25 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
26 #include <BRep_PolygonOnTriangulation.hxx>
27 #include <BRep_TEdge.hxx>
28 #include <BRep_Tool.hxx>
29 #include <Geom_Surface.hxx>
30 #include <NCollection_Map.hxx>
31 #include <Poly_PolygonOnTriangulation.hxx>
32 #include <Poly_Triangulation.hxx>
33 #include <Precision.hxx>
34 #include <TColgp_Array1OfPnt2d.hxx>
36 #include <TopExp_Explorer.hxx>
37 #include <TopLoc_Location.hxx>
38 #include <TopTools_MapOfShape.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Edge.hxx>
42 #include <TShort_Array1OfShortReal.hxx>
45 IMPLEMENT_STANDARD_HANDLE (NIS_Surface, NIS_InteractiveObject)
46 IMPLEMENT_STANDARD_RTTIEXT(NIS_Surface, NIS_InteractiveObject)
48 //=======================================================================
50 //purpose : Compare two triangulations, for NCollection_Map interface.
51 //=======================================================================
53 inline Standard_Boolean IsEqual(const Handle_Poly_Triangulation& theT0,
54 const Handle_Poly_Triangulation& theT1)
56 return (theT0 == theT1);
59 //=======================================================================
60 //function : NIS_Surface
62 //=======================================================================
64 NIS_Surface::NIS_Surface(const Handle_NCollection_BaseAllocator& theAlloc)
76 myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
79 //=======================================================================
80 //function : NIS_Surface
82 //=======================================================================
84 NIS_Surface::NIS_Surface (const Handle(Poly_Triangulation)& theTri,
85 const Handle_NCollection_BaseAllocator& theAlloc)
96 myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
97 if (theTri.IsNull() == Standard_False)
99 // Alocate arrays of entities
100 myNNodes = 3 * theTri->NbTriangles();
101 myNTriangles = theTri->NbTriangles();
102 mypNodes = static_cast<Standard_ShortReal*>
103 (myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
104 mypNormals = static_cast<Standard_ShortReal *>
105 (myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
106 mypTriangles = static_cast<Standard_Integer*>
107 (myAlloc->Allocate(sizeof(Standard_Integer) * 3 * myNTriangles));
109 // Copy the data from the original triangulation.
110 Standard_Integer i, iN(0), iT(0);
111 const Poly_Array1OfTriangle& arrTri = theTri->Triangles();
112 const TColgp_Array1OfPnt& arrNodes = theTri->Nodes();
113 for (i = arrTri.Lower(); i <= arrTri.Upper(); i++) {
114 Standard_Integer iNode[3];
115 arrTri(i).Get(iNode[0], iNode[1], iNode[2]);
116 gp_XYZ aNorm = ((arrNodes(iNode[1]).XYZ() - arrNodes(iNode[0]).XYZ()) ^
117 (arrNodes(iNode[2]).XYZ() - arrNodes(iNode[0]).XYZ()));
118 const Standard_Real aMagn = aNorm.Modulus();
119 if (aMagn > Precision::Confusion())
122 aNorm.SetCoord(0., 0., 1.);
123 mypNodes[iN+0] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).X());
124 mypNodes[iN+1] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).Y());
125 mypNodes[iN+2] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).Z());
126 mypNodes[iN+3] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).X());
127 mypNodes[iN+4] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).Y());
128 mypNodes[iN+5] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).Z());
129 mypNodes[iN+6] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).X());
130 mypNodes[iN+7] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).Y());
131 mypNodes[iN+8] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).Z());
132 mypNormals[iN+0] = static_cast<Standard_ShortReal>(aNorm.X());
133 mypNormals[iN+1] = static_cast<Standard_ShortReal>(aNorm.Y());
134 mypNormals[iN+2] = static_cast<Standard_ShortReal>(aNorm.Z());
135 mypNormals[iN+3] = static_cast<Standard_ShortReal>(aNorm.X());
136 mypNormals[iN+4] = static_cast<Standard_ShortReal>(aNorm.Y());
137 mypNormals[iN+5] = static_cast<Standard_ShortReal>(aNorm.Z());
138 mypNormals[iN+6] = static_cast<Standard_ShortReal>(aNorm.X());
139 mypNormals[iN+7] = static_cast<Standard_ShortReal>(aNorm.Y());
140 mypNormals[iN+8] = static_cast<Standard_ShortReal>(aNorm.Z());
141 mypTriangles[iT+0] = iT+0;
142 mypTriangles[iT+1] = iT+1;
143 mypTriangles[iT+2] = iT+2;
150 //=======================================================================
151 //function : NIS_Surface
152 //purpose : Constructor
153 //=======================================================================
155 NIS_Surface::NIS_Surface (const TopoDS_Shape& theShape,
156 const Standard_Real theDeflection,
157 const Handle_NCollection_BaseAllocator& theAlloc)
158 : myAlloc (theAlloc),
168 if (myAlloc.IsNull())
169 myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
170 Init (theShape, theDeflection);
173 //=======================================================================
175 //purpose : Initialize the instance with a TopoDS_Shape.
176 //=======================================================================
178 void NIS_Surface::Init (const TopoDS_Shape& theShape,
179 const Standard_Real theDeflection)
181 TopLoc_Location aLoc, aLocSurf;
183 // Count the nodes and triangles in faces
184 NCollection_Map<Handle_Poly_Triangulation> mapTri;
185 TopExp_Explorer fexp (theShape, TopAbs_FACE);
186 for (; fexp.More(); fexp.Next())
188 const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
190 const Handle(Poly_Triangulation)& aTriangulation
191 = BRep_Tool::Triangulation (aFace, aLoc);
193 if (aTriangulation.IsNull())
194 BRepMesh_IncrementalMesh aMeshTool(aFace, theDeflection);
196 if (aTriangulation.IsNull() == Standard_False)
198 myNNodes += aTriangulation->NbNodes();
199 myNTriangles += aTriangulation->NbTriangles();
200 mapTri.Add(aTriangulation);
204 // Create map of edges, to build wireframe for all edges.
205 TopTools_MapOfShape mapEdges;
206 TopExp_Explorer eexp (theShape, TopAbs_EDGE);
207 for (; eexp.More(); eexp.Next())
209 const TopoDS_Shape& anEdge = eexp.Current();
210 mapEdges.Add(anEdge);
213 // Allocate arrays of entities
214 if (myNNodes && myNTriangles) {
215 mypNodes = static_cast<Standard_ShortReal *>
216 (myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
217 mypNormals = static_cast<Standard_ShortReal *>
218 (myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
219 mypTriangles = static_cast<Standard_Integer *>
220 (myAlloc->Allocate(sizeof(Standard_Integer) * 3 * myNTriangles));
221 mypEdges = static_cast<Standard_Integer **>
222 (myAlloc->Allocate(sizeof(Standard_Integer *) * mapEdges.Extent()));
225 // The second loop: copy all nodes and triangles face-by-face
226 const Standard_Real eps2 = Precision::SquareConfusion();
227 Standard_Integer nNodes (0), nTriangles (0);
228 for (fexp.ReInit(); fexp.More(); fexp.Next())
230 const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
231 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLocSurf);
232 const Handle(Poly_Triangulation)& aTriangulation =
233 BRep_Tool::Triangulation(aFace, aLoc);
234 if (aTriangulation.IsNull() == Standard_False)
236 // Prepare transformation
237 Standard_Integer i, aNodeInd(nNodes)/*, aNTriangles = 0*/;
238 const gp_Trsf& aTrf = aLoc.Transformation();
239 const gp_Trsf& aTrfSurf = aLocSurf.Transformation();
240 Standard_Boolean isReverse = (aFace.Orientation() == TopAbs_REVERSED);
242 // Store all nodes of the current face in the data model
243 const TColgp_Array1OfPnt& tabNode = aTriangulation->Nodes();
244 const TColgp_Array1OfPnt2d& tabUV = aTriangulation->UVNodes();
245 for (i = tabNode.Lower(); i <= tabNode.Upper(); i++)
248 tabNode(i).Transformed(aTrf).Coord (t[0], t[1], t[2]);
249 // write node to mesh data
250 mypNodes[3*aNodeInd + 0] = static_cast<Standard_ShortReal>(t[0]);
251 mypNodes[3*aNodeInd + 1] = static_cast<Standard_ShortReal>(t[1]);
252 mypNodes[3*aNodeInd + 2] = static_cast<Standard_ShortReal>(t[2]);
256 gp_XYZ aNorm(0., 0., 0.);
258 if (aTriangulation->HasNormals()) {
259 // Retrieve the normal direction from the triangulation
260 aNorm.SetCoord(aTriangulation->Normals().Value(3*i-2),
261 aTriangulation->Normals().Value(3*i-1),
262 aTriangulation->Normals().Value(3*i-0));
263 } else if (aSurf.IsNull() == Standard_False)
265 // Compute the surface normal at the Node.
266 aSurf->D1(tabUV(i).X(), tabUV(i).Y(), aP, aD1U, aD1V);
267 aNorm = (aD1U.Crossed(aD1V)).XYZ();
272 const Standard_Real aMod = aNorm.SquareModulus();
274 gp_Dir aDirNorm(aNorm);
275 aDirNorm.Transform(aTrfSurf);
276 aDirNorm.Coord (t[0], t[1], t[2]);
282 mypNormals[3*aNodeInd + 0] = static_cast<Standard_ShortReal>(t[0]);
283 mypNormals[3*aNodeInd + 1] = static_cast<Standard_ShortReal>(t[1]);
284 mypNormals[3*aNodeInd + 2] = static_cast<Standard_ShortReal>(t[2]);
288 const Standard_Integer nNodes1 = nNodes - 1;
289 // Store all triangles of the current face in the data model
290 const Poly_Array1OfTriangle& tabTri = aTriangulation->Triangles();
291 for (i = tabTri.Lower(); i <= tabTri.Upper(); i++)
293 Standard_Integer aN[3];
294 tabTri(i).Get (aN[0], aN[1], aN[2]);
295 Standard_Integer * pTriangle = &mypTriangles[nTriangles*3];
296 pTriangle[0] = aN[0] + nNodes1;
298 pTriangle[1] = aN[2] + nNodes1;
299 pTriangle[2] = aN[1] + nNodes1;
301 pTriangle[1] = aN[1] + nNodes1;
302 pTriangle[2] = aN[2] + nNodes1;
304 const Standard_ShortReal aVec0[3] = {
305 mypNodes[3*pTriangle[1]+0] - mypNodes[3*pTriangle[0]+0],
306 mypNodes[3*pTriangle[1]+1] - mypNodes[3*pTriangle[0]+1],
307 mypNodes[3*pTriangle[1]+2] - mypNodes[3*pTriangle[0]+2]
309 const Standard_ShortReal aVec1[3] = {
310 mypNodes[3*pTriangle[2]+0] - mypNodes[3*pTriangle[0]+0],
311 mypNodes[3*pTriangle[2]+1] - mypNodes[3*pTriangle[0]+1],
312 mypNodes[3*pTriangle[2]+2] - mypNodes[3*pTriangle[0]+2]
314 const Standard_ShortReal aVecP[3] = {
315 aVec0[1] * aVec1[2] - aVec0[2] * aVec1[1],
316 aVec0[2] * aVec1[0] - aVec0[0] * aVec1[2],
317 aVec0[0] * aVec1[1] - aVec0[1] * aVec1[0]
319 if (aVecP[0]*aVecP[0] + aVecP[1]*aVecP[1] + aVecP[2]*aVecP[2] > eps2)
322 // Store all edge polygons on the current face.
323 for (eexp.Init(aFace, TopAbs_EDGE); eexp.More(); eexp.Next())
325 const TopoDS_Edge& anEdge = TopoDS::Edge(eexp.Current());
326 if (mapEdges.Remove(anEdge)) {
327 const Handle(Poly_PolygonOnTriangulation)& aPolygon =
328 BRep_Tool::PolygonOnTriangulation(anEdge, aTriangulation, aLoc);
329 if (aPolygon.IsNull() == Standard_False) {
330 const TColStd_Array1OfInteger& arrNode = aPolygon->Nodes();
331 // Allocate memory to store the current polygon indices.
332 Standard_Integer aLen = arrNode.Length();
333 Standard_Integer * pEdge = static_cast<Standard_Integer *>
334 (myAlloc->Allocate(sizeof(Standard_Integer) * (aLen + 1)));
335 const gp_Pnt* pLast = &tabNode(arrNode(arrNode.Lower()));
336 pEdge[1] = arrNode(arrNode.Lower()) + nNodes1;
337 Standard_Integer iPNode(arrNode.Lower() + 1), iENode(1);
338 for (; iPNode <= arrNode.Upper(); iPNode++)
340 const Standard_Integer aN(arrNode(iPNode));
341 if (pLast->SquareDistance(tabNode(aN)) < eps2)
345 pLast = &tabNode(aN);
346 pEdge[++iENode] = aN + nNodes1;
349 // Do not save very short polygons
352 mypEdges[myNEdges++] = pEdge;
357 nNodes += tabNode.Length();
360 myNTriangles = nTriangles;
362 if (GetDrawer().IsNull() == Standard_False)
366 setIsUpdateBox(Standard_True);
369 //=======================================================================
370 //function : ~NIS_Surface
371 //purpose : Destructor
372 //=======================================================================
374 NIS_Surface::~NIS_Surface ()
379 //=======================================================================
382 //=======================================================================
384 void NIS_Surface::Clear ()
388 myAlloc->Free(mypNodes);
389 myAlloc->Free(mypNormals);
393 myAlloc->Free(mypTriangles);
396 for (Standard_Integer i = 0; i < myNEdges; i++) {
397 myAlloc->Free(mypEdges[i]);
400 myAlloc->Free(mypEdges);
402 if (GetDrawer().IsNull() == Standard_False) {
403 GetDrawer()->SetUpdated(NIS_Drawer::Draw_Normal,
404 NIS_Drawer::Draw_Top,
405 NIS_Drawer::Draw_Transparent,
406 NIS_Drawer::Draw_Hilighted);
411 //=======================================================================
412 //function : DefaultDrawer
414 //=======================================================================
416 NIS_Drawer * NIS_Surface::DefaultDrawer (NIS_Drawer * theDrawer) const
418 NIS_SurfaceDrawer * aDrawer =
419 theDrawer ? static_cast<NIS_SurfaceDrawer *>(theDrawer)
420 : new NIS_SurfaceDrawer (Quantity_NOC_SLATEBLUE4);
421 aDrawer->SetBackColor (Quantity_NOC_DARKGREEN);
422 aDrawer->myIsWireframe = myIsWireframe;
426 //=======================================================================
427 //function : SetColor
428 //purpose : Set the normal color for presentation.
429 //=======================================================================
431 void NIS_Surface::SetColor (const Quantity_Color& theColor)
433 const Handle(NIS_SurfaceDrawer) aDrawer =
434 static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
435 aDrawer->Assign (GetDrawer());
436 aDrawer->myColor[NIS_Drawer::Draw_Normal] = theColor;
437 aDrawer->myColor[NIS_Drawer::Draw_Top] = theColor;
438 aDrawer->myColor[NIS_Drawer::Draw_Transparent] = theColor;
442 //=======================================================================
443 //function : SetBackColor
444 //purpose : Set the normal color for presentation of back side of triangles.
445 //=======================================================================
447 void NIS_Surface::SetBackColor (const Quantity_Color& theColor)
449 const Handle(NIS_SurfaceDrawer) aDrawer =
450 static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
451 aDrawer->Assign (GetDrawer());
452 aDrawer->myBackColor = theColor;
456 //=======================================================================
457 //function : SetPolygonOffset
459 //=======================================================================
461 void NIS_Surface::SetPolygonOffset (const Standard_Real theValue)
463 const Handle(NIS_SurfaceDrawer) aDrawer =
464 static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
465 aDrawer->Assign (GetDrawer());
466 aDrawer->myPolygonOffset = static_cast<Standard_ShortReal>(theValue);
470 //=======================================================================
471 //function : SetDisplayMode
472 //purpose : Set the display mode: Shading or Wireframe.
473 //=======================================================================
475 void NIS_Surface::SetDisplayMode (const NIS_Surface::DisplayMode theMode)
477 Standard_Boolean isUpdate(Standard_False);
479 if (theMode != Wireframe) {
480 myIsWireframe = Standard_False;
481 isUpdate = Standard_True;
484 if (theMode == Wireframe) {
485 myIsWireframe = Standard_True;
486 isUpdate = Standard_True;
489 if (isUpdate && !GetDrawer().IsNull()) {
490 const Handle(NIS_SurfaceDrawer) aDrawer =
491 static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
492 aDrawer->Assign (GetDrawer());
493 aDrawer->myIsWireframe = myIsWireframe;
498 //=======================================================================
499 //function : GetDisplayMode
500 //purpose : Query the current display mode: Shading or Wireframe.
501 //=======================================================================
503 NIS_Surface::DisplayMode NIS_Surface::GetDisplayMode () const
505 return myIsWireframe ? Wireframe : Shading;
508 //=======================================================================
511 //=======================================================================
513 void NIS_Surface::Clone (const Handle_NCollection_BaseAllocator& theAlloc,
514 Handle_NIS_InteractiveObject& theDest) const
516 Handle(NIS_Surface) aNewObj;
517 if (theDest.IsNull()) {
518 aNewObj = new NIS_Surface(theAlloc);
521 aNewObj = reinterpret_cast<NIS_Surface*> (theDest.operator->());
522 aNewObj->myAlloc = theAlloc;
524 NIS_InteractiveObject::Clone(theAlloc, theDest);
525 aNewObj->myNNodes = myNNodes;
527 // copy nodes and normals
528 const Standard_Size nBytes = myNNodes*3*sizeof(Standard_ShortReal);
529 aNewObj->mypNodes = (Standard_ShortReal *)theAlloc->Allocate(nBytes);
530 aNewObj->mypNormals = (Standard_ShortReal *)theAlloc->Allocate(nBytes);
531 memcpy(aNewObj->mypNodes, mypNodes, nBytes);
532 memcpy(aNewObj->mypNormals, mypNormals, nBytes);
534 aNewObj->myNTriangles = myNTriangles;
535 if (myNTriangles > 0) {
536 const Standard_Size nBytes = sizeof(Standard_Integer) * 3 * myNTriangles;
537 aNewObj->mypTriangles = (Standard_Integer *)theAlloc->Allocate(nBytes);
538 memcpy(aNewObj->mypTriangles, mypTriangles, nBytes);
540 aNewObj->myNEdges = myNEdges;
542 aNewObj->mypEdges = static_cast<Standard_Integer **>
543 (theAlloc->Allocate(sizeof(Standard_Integer *) * myNEdges));
544 for (Standard_Integer i = 0; i < myNEdges; i++) {
545 const Standard_Integer * pEdge = mypEdges[i];
546 const Standard_Size nBytes = sizeof(Standard_Integer) * (pEdge[0] + 1);
547 aNewObj->mypEdges[i] =
548 static_cast<Standard_Integer *> (theAlloc->Allocate(nBytes));
549 memcpy(aNewObj->mypEdges[i], pEdge, nBytes);
552 aNewObj->myIsWireframe = myIsWireframe;
555 //=======================================================================
556 //function : Intersect
558 //=======================================================================
560 Standard_Real NIS_Surface::Intersect (const gp_Ax1& theAxis,
561 const Standard_Real theOver) const
563 Standard_Real aResult (RealLast());
564 Standard_Real start[3], dir[3];
565 theAxis.Location().Coord(start[0], start[1], start[2]);
566 theAxis.Direction().Coord(dir[0], dir[1], dir[2]);
569 if (myIsWireframe == Standard_False)
570 for (Standard_Integer i = 0; i < myNTriangles; i++) {
571 const Standard_Integer * pTri = &mypTriangles[3*i];
572 if (NIS_Triangulated::tri_line_intersect (start, dir,
573 &mypNodes[3*pTri[0]],
574 &mypNodes[3*pTri[1]],
575 &mypNodes[3*pTri[2]],
577 if (anInter < aResult)
581 const Standard_Real anOver2 = theOver*theOver;
582 for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
583 const Standard_Integer * anEdge = mypEdges[iEdge];
584 const Standard_Integer nNodes = anEdge[0];
585 for (Standard_Integer i = 1; i < nNodes; i++) {
586 // Node index is incremented for the head of polygon indice array
587 if (NIS_Triangulated::seg_line_intersect (theAxis.Location().XYZ(),
588 theAxis.Direction().XYZ(),
590 &mypNodes[3*anEdge[i+0]],
591 &mypNodes[3*anEdge[i+1]],
593 if (anInter < aResult)
602 //=======================================================================
603 //function : Intersect
605 //=======================================================================
607 Standard_Boolean NIS_Surface::Intersect (const Bnd_B3f& theBox,
608 const gp_Trsf& theTrf,
609 const Standard_Boolean isFullIn) const
611 Standard_Boolean aResult (isFullIn);
613 if (myIsWireframe == Standard_False) {
614 if (myNTriangles > 0) {
615 for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
616 gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
617 static_cast<Standard_Real>(mypNodes[iNode+1]),
618 static_cast<Standard_Real>(mypNodes[iNode+2]));
619 theTrf.Transforms(aPnt);
620 if (theBox.IsOut (aPnt) == isFullIn) {
627 for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
628 const Standard_Integer * anEdge = mypEdges[iEdge];
629 const Standard_Integer nNodes = anEdge[0];
630 for (Standard_Integer i = 1; i < nNodes; i++) {
631 // index is incremented by 1 for the head number in the array
633 gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
634 static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
635 static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
636 gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
637 static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
638 static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
640 aPnt[0].Transform(theTrf);
641 aPnt[1].Transform(theTrf);
643 if (NIS_Triangulated::seg_box_included (theBox, aPnt) == 0) {
644 aResult = Standard_False;
648 if (NIS_Triangulated::seg_box_intersect (theBox, aPnt)) {
649 aResult = Standard_True;
659 //=======================================================================
660 //function : Intersect
661 //purpose : Selection by polygon
662 //=======================================================================
664 Standard_Boolean NIS_Surface::Intersect
665 (const NCollection_List<gp_XY> &thePolygon,
666 const gp_Trsf &theTrf,
667 const Standard_Boolean isFullIn) const
669 Standard_Boolean aResult (isFullIn);
671 if (myIsWireframe == Standard_False) {
672 if (myNTriangles > 0) {
673 for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
674 gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
675 static_cast<Standard_Real>(mypNodes[iNode+1]),
676 static_cast<Standard_Real>(mypNodes[iNode+2]));
677 theTrf.Transforms(aPnt);
678 gp_XY aP2d(aPnt.X(), aPnt.Y());
680 if (!NIS_Triangulated::IsIn(thePolygon, aP2d)) {
682 aResult = Standard_False;
686 if (isFullIn == Standard_False) {
687 aResult = Standard_True;
694 for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
695 const Standard_Integer * anEdge = mypEdges[iEdge];
696 const Standard_Integer nNodes = anEdge[0];
697 for (Standard_Integer i = 1; i < nNodes; i++) {
698 // index is incremented by 1 for the head number in the array
700 gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
701 static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
702 static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
703 gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
704 static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
705 static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
707 aPnt[0].Transform(theTrf);
708 aPnt[1].Transform(theTrf);
709 const gp_XY aP2d[2] = { gp_XY(aPnt[0].X(), aPnt[0].Y()),
710 gp_XY(aPnt[1].X(), aPnt[1].Y()) };
712 if (NIS_Triangulated::seg_polygon_included (thePolygon, aP2d) == 0) {
713 aResult = Standard_False;
717 if (NIS_Triangulated::seg_polygon_intersect (thePolygon, aP2d)) {
718 aResult = Standard_True;
728 //=======================================================================
729 //function : computeBox
731 //=======================================================================
733 void NIS_Surface::computeBox ()
735 NIS_Triangulated::ComputeBox(myBox, myNNodes, mypNodes, 3);
737 const Handle(NIS_SurfaceDrawer)& aDrawer =
738 static_cast<const Handle(NIS_SurfaceDrawer)&> (GetDrawer());
740 if (aDrawer.IsNull() == Standard_False) {
741 const gp_Trsf& aTrsf = aDrawer->GetTransformation();
742 myBox = myBox.Transformed(aTrsf);