1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/NIS/NIS_Surface.cxx
abk 08cd2f6bb1 0023404: Create SquareConfusion function in Precision package for speed and convenience
SquareConfusion function was created in FoundationClasses module -> TKMath toolkit -> Precision package.
The function returns square of Precision::Confusion().
SquareConfusion function was corrected in FoundationClasses module -> TKMath toolkit -> Precision package.
Squares of Precision::Confusion() were replaced by Precision::SquareConfusion().
2012-10-05 13:55:16 +04:00

745 lines
28 KiB
C++
Executable File

// Created on: 2008-03-20
// Created by: Alexander GRIGORIEV
// Copyright (c) 2008-2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#include <NIS_Surface.hxx>
#include <NIS_SurfaceDrawer.hxx>
#include <NIS_Triangulated.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
#include <BRep_PolygonOnTriangulation.hxx>
#include <BRep_TEdge.hxx>
#include <BRep_Tool.hxx>
#include <Geom_Surface.hxx>
#include <NCollection_Map.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Triangulation.hxx>
#include <Precision.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
#include <TShort_Array1OfShortReal.hxx>
#include <gp_Ax1.hxx>
IMPLEMENT_STANDARD_HANDLE (NIS_Surface, NIS_InteractiveObject)
IMPLEMENT_STANDARD_RTTIEXT(NIS_Surface, NIS_InteractiveObject)
//=======================================================================
//function : IsEqual
//purpose : Compare two triangulations, for NCollection_Map interface.
//=======================================================================
inline Standard_Boolean IsEqual(const Handle_Poly_Triangulation& theT0,
const Handle_Poly_Triangulation& theT1)
{
return (theT0 == theT1);
}
//=======================================================================
//function : NIS_Surface
//purpose :
//=======================================================================
NIS_Surface::NIS_Surface(const Handle_NCollection_BaseAllocator& theAlloc)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
mypTriangles (NULL),
mypEdges (NULL),
myNNodes (0),
myNTriangles (0),
myNEdges (0),
myIsWireframe(0)
{
if (myAlloc.IsNull())
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
}
//=======================================================================
//function : NIS_Surface
//purpose :
//=======================================================================
NIS_Surface::NIS_Surface (const Handle(Poly_Triangulation)& theTri,
const Handle_NCollection_BaseAllocator& theAlloc)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
mypEdges (NULL),
myNNodes (0),
myNTriangles (0),
myNEdges (0),
myIsWireframe(0)
{
if (myAlloc.IsNull())
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
if (theTri.IsNull() == Standard_False)
{
// Alocate arrays of entities
myNNodes = 3 * theTri->NbTriangles();
myNTriangles = theTri->NbTriangles();
mypNodes = static_cast<Standard_ShortReal*>
(myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
mypNormals = static_cast<Standard_ShortReal *>
(myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
mypTriangles = static_cast<Standard_Integer*>
(myAlloc->Allocate(sizeof(Standard_Integer) * 3 * myNTriangles));
// Copy the data from the original triangulation.
Standard_Integer i, iN(0), iT(0);
const Poly_Array1OfTriangle& arrTri = theTri->Triangles();
const TColgp_Array1OfPnt& arrNodes = theTri->Nodes();
for (i = arrTri.Lower(); i <= arrTri.Upper(); i++) {
Standard_Integer iNode[3];
arrTri(i).Get(iNode[0], iNode[1], iNode[2]);
gp_XYZ aNorm = ((arrNodes(iNode[1]).XYZ() - arrNodes(iNode[0]).XYZ()) ^
(arrNodes(iNode[2]).XYZ() - arrNodes(iNode[0]).XYZ()));
const Standard_Real aMagn = aNorm.Modulus();
if (aMagn > Precision::Confusion())
aNorm /= aMagn;
else
aNorm.SetCoord(0., 0., 1.);
mypNodes[iN+0] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).X());
mypNodes[iN+1] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).Y());
mypNodes[iN+2] = static_cast<Standard_ShortReal>(arrNodes(iNode[0]).Z());
mypNodes[iN+3] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).X());
mypNodes[iN+4] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).Y());
mypNodes[iN+5] = static_cast<Standard_ShortReal>(arrNodes(iNode[1]).Z());
mypNodes[iN+6] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).X());
mypNodes[iN+7] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).Y());
mypNodes[iN+8] = static_cast<Standard_ShortReal>(arrNodes(iNode[2]).Z());
mypNormals[iN+0] = static_cast<Standard_ShortReal>(aNorm.X());
mypNormals[iN+1] = static_cast<Standard_ShortReal>(aNorm.Y());
mypNormals[iN+2] = static_cast<Standard_ShortReal>(aNorm.Z());
mypNormals[iN+3] = static_cast<Standard_ShortReal>(aNorm.X());
mypNormals[iN+4] = static_cast<Standard_ShortReal>(aNorm.Y());
mypNormals[iN+5] = static_cast<Standard_ShortReal>(aNorm.Z());
mypNormals[iN+6] = static_cast<Standard_ShortReal>(aNorm.X());
mypNormals[iN+7] = static_cast<Standard_ShortReal>(aNorm.Y());
mypNormals[iN+8] = static_cast<Standard_ShortReal>(aNorm.Z());
mypTriangles[iT+0] = iT+0;
mypTriangles[iT+1] = iT+1;
mypTriangles[iT+2] = iT+2;
iN += 9;
iT += 3;
}
}
}
//=======================================================================
//function : NIS_Surface
//purpose : Constructor
//=======================================================================
NIS_Surface::NIS_Surface (const TopoDS_Shape& theShape,
const Standard_Real theDeflection,
const Handle_NCollection_BaseAllocator& theAlloc)
: myAlloc (theAlloc),
mypNodes (NULL),
mypNormals (NULL),
mypTriangles (NULL),
mypEdges (NULL),
myNNodes (0),
myNTriangles (0),
myNEdges (0),
myIsWireframe (0)
{
if (myAlloc.IsNull())
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
Init (theShape, theDeflection);
}
//=======================================================================
//function : Init
//purpose : Initialize the instance with a TopoDS_Shape.
//=======================================================================
void NIS_Surface::Init (const TopoDS_Shape& theShape,
const Standard_Real theDeflection)
{
TopLoc_Location aLoc, aLocSurf;
// Count the nodes and triangles in faces
NCollection_Map<Handle_Poly_Triangulation> mapTri;
TopExp_Explorer fexp (theShape, TopAbs_FACE);
for (; fexp.More(); fexp.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
const Handle(Poly_Triangulation)& aTriangulation
= BRep_Tool::Triangulation (aFace, aLoc);
if (aTriangulation.IsNull())
BRepMesh_IncrementalMesh aMeshTool(aFace, theDeflection);
if (aTriangulation.IsNull() == Standard_False)
{
myNNodes += aTriangulation->NbNodes();
myNTriangles += aTriangulation->NbTriangles();
mapTri.Add(aTriangulation);
}
}
// Create map of edges, to build wireframe for all edges.
TopTools_MapOfShape mapEdges;
TopExp_Explorer eexp (theShape, TopAbs_EDGE);
for (; eexp.More(); eexp.Next())
{
const TopoDS_Shape& anEdge = eexp.Current();
mapEdges.Add(anEdge);
}
// Allocate arrays of entities
if (myNNodes && myNTriangles) {
mypNodes = static_cast<Standard_ShortReal *>
(myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
mypNormals = static_cast<Standard_ShortReal *>
(myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
mypTriangles = static_cast<Standard_Integer *>
(myAlloc->Allocate(sizeof(Standard_Integer) * 3 * myNTriangles));
mypEdges = static_cast<Standard_Integer **>
(myAlloc->Allocate(sizeof(Standard_Integer *) * mapEdges.Extent()));
myNEdges = 0;
// The second loop: copy all nodes and triangles face-by-face
const Standard_Real eps2 = Precision::SquareConfusion();
Standard_Integer nNodes (0), nTriangles (0);
for (fexp.ReInit(); fexp.More(); fexp.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLocSurf);
const Handle(Poly_Triangulation)& aTriangulation =
BRep_Tool::Triangulation(aFace, aLoc);
if (aTriangulation.IsNull() == Standard_False)
{
// Prepare transformation
Standard_Integer i, aNodeInd(nNodes)/*, aNTriangles = 0*/;
const gp_Trsf& aTrf = aLoc.Transformation();
const gp_Trsf& aTrfSurf = aLocSurf.Transformation();
Standard_Boolean isReverse = (aFace.Orientation() == TopAbs_REVERSED);
// Store all nodes of the current face in the data model
const TColgp_Array1OfPnt& tabNode = aTriangulation->Nodes();
const TColgp_Array1OfPnt2d& tabUV = aTriangulation->UVNodes();
for (i = tabNode.Lower(); i <= tabNode.Upper(); i++)
{
Standard_Real t[3];
tabNode(i).Transformed(aTrf).Coord (t[0], t[1], t[2]);
// write node to mesh data
mypNodes[3*aNodeInd + 0] = static_cast<Standard_ShortReal>(t[0]);
mypNodes[3*aNodeInd + 1] = static_cast<Standard_ShortReal>(t[1]);
mypNodes[3*aNodeInd + 2] = static_cast<Standard_ShortReal>(t[2]);
gp_Vec aD1U, aD1V;
gp_Pnt aP;
gp_XYZ aNorm(0., 0., 0.);
if (aTriangulation->HasNormals()) {
// Retrieve the normal direction from the triangulation
aNorm.SetCoord(aTriangulation->Normals().Value(3*i-2),
aTriangulation->Normals().Value(3*i-1),
aTriangulation->Normals().Value(3*i-0));
} else if (aSurf.IsNull() == Standard_False)
{
// Compute the surface normal at the Node.
aSurf->D1(tabUV(i).X(), tabUV(i).Y(), aP, aD1U, aD1V);
aNorm = (aD1U.Crossed(aD1V)).XYZ();
}
if (isReverse)
aNorm.Reverse();
const Standard_Real aMod = aNorm.SquareModulus();
if (aMod > eps2) {
gp_Dir aDirNorm(aNorm);
aDirNorm.Transform(aTrfSurf);
aDirNorm.Coord (t[0], t[1], t[2]);
} else {
t[0] = 0.;
t[1] = 0.;
t[2] = 1.;
}
mypNormals[3*aNodeInd + 0] = static_cast<Standard_ShortReal>(t[0]);
mypNormals[3*aNodeInd + 1] = static_cast<Standard_ShortReal>(t[1]);
mypNormals[3*aNodeInd + 2] = static_cast<Standard_ShortReal>(t[2]);
aNodeInd++;
}
const Standard_Integer nNodes1 = nNodes - 1;
// Store all triangles of the current face in the data model
const Poly_Array1OfTriangle& tabTri = aTriangulation->Triangles();
for (i = tabTri.Lower(); i <= tabTri.Upper(); i++)
{
Standard_Integer aN[3];
tabTri(i).Get (aN[0], aN[1], aN[2]);
Standard_Integer * pTriangle = &mypTriangles[nTriangles*3];
pTriangle[0] = aN[0] + nNodes1;
if (isReverse) {
pTriangle[1] = aN[2] + nNodes1;
pTriangle[2] = aN[1] + nNodes1;
} else {
pTriangle[1] = aN[1] + nNodes1;
pTriangle[2] = aN[2] + nNodes1;
}
const Standard_ShortReal aVec0[3] = {
mypNodes[3*pTriangle[1]+0] - mypNodes[3*pTriangle[0]+0],
mypNodes[3*pTriangle[1]+1] - mypNodes[3*pTriangle[0]+1],
mypNodes[3*pTriangle[1]+2] - mypNodes[3*pTriangle[0]+2]
};
const Standard_ShortReal aVec1[3] = {
mypNodes[3*pTriangle[2]+0] - mypNodes[3*pTriangle[0]+0],
mypNodes[3*pTriangle[2]+1] - mypNodes[3*pTriangle[0]+1],
mypNodes[3*pTriangle[2]+2] - mypNodes[3*pTriangle[0]+2]
};
const Standard_ShortReal aVecP[3] = {
aVec0[1] * aVec1[2] - aVec0[2] * aVec1[1],
aVec0[2] * aVec1[0] - aVec0[0] * aVec1[2],
aVec0[0] * aVec1[1] - aVec0[1] * aVec1[0]
};
if (aVecP[0]*aVecP[0] + aVecP[1]*aVecP[1] + aVecP[2]*aVecP[2] > eps2)
nTriangles++;
}
// Store all edge polygons on the current face.
for (eexp.Init(aFace, TopAbs_EDGE); eexp.More(); eexp.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(eexp.Current());
if (mapEdges.Remove(anEdge)) {
const Handle(Poly_PolygonOnTriangulation)& aPolygon =
BRep_Tool::PolygonOnTriangulation(anEdge, aTriangulation, aLoc);
if (aPolygon.IsNull() == Standard_False) {
const TColStd_Array1OfInteger& arrNode = aPolygon->Nodes();
// Allocate memory to store the current polygon indices.
Standard_Integer aLen = arrNode.Length();
Standard_Integer * pEdge = static_cast<Standard_Integer *>
(myAlloc->Allocate(sizeof(Standard_Integer) * (aLen + 1)));
const gp_Pnt* pLast = &tabNode(arrNode(arrNode.Lower()));
pEdge[1] = arrNode(arrNode.Lower()) + nNodes1;
Standard_Integer iPNode(arrNode.Lower() + 1), iENode(1);
for (; iPNode <= arrNode.Upper(); iPNode++)
{
const Standard_Integer aN(arrNode(iPNode));
if (pLast->SquareDistance(tabNode(aN)) < eps2)
{
aLen--;
} else {
pLast = &tabNode(aN);
pEdge[++iENode] = aN + nNodes1;
}
}
// Do not save very short polygons
if (aLen > 1) {
pEdge[0] = aLen;
mypEdges[myNEdges++] = pEdge;
}
}
}
}
nNodes += tabNode.Length();
}
}
myNTriangles = nTriangles;
}
if (GetDrawer().IsNull() == Standard_False)
{
setDrawerUpdate();
}
setIsUpdateBox(Standard_True);
}
//=======================================================================
//function : ~NIS_Surface
//purpose : Destructor
//=======================================================================
NIS_Surface::~NIS_Surface ()
{
Clear();
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void NIS_Surface::Clear ()
{
if (myNNodes) {
myNNodes = 0;
myAlloc->Free(mypNodes);
myAlloc->Free(mypNormals);
}
if (myNTriangles) {
myNTriangles = 0;
myAlloc->Free(mypTriangles);
}
if (mypEdges) {
for (Standard_Integer i = 0; i < myNEdges; i++) {
myAlloc->Free(mypEdges[i]);
}
myNEdges = 0;
myAlloc->Free(mypEdges);
}
if (GetDrawer().IsNull() == Standard_False) {
GetDrawer()->SetUpdated(NIS_Drawer::Draw_Normal,
NIS_Drawer::Draw_Top,
NIS_Drawer::Draw_Transparent,
NIS_Drawer::Draw_Hilighted);
}
myBox.Clear();
}
//=======================================================================
//function : DefaultDrawer
//purpose :
//=======================================================================
NIS_Drawer * NIS_Surface::DefaultDrawer (NIS_Drawer * theDrawer) const
{
NIS_SurfaceDrawer * aDrawer =
theDrawer ? static_cast<NIS_SurfaceDrawer *>(theDrawer)
: new NIS_SurfaceDrawer (Quantity_NOC_SLATEBLUE4);
aDrawer->SetBackColor (Quantity_NOC_DARKGREEN);
aDrawer->myIsWireframe = myIsWireframe;
return aDrawer;
}
//=======================================================================
//function : SetColor
//purpose : Set the normal color for presentation.
//=======================================================================
void NIS_Surface::SetColor (const Quantity_Color& theColor)
{
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myColor[NIS_Drawer::Draw_Normal] = theColor;
aDrawer->myColor[NIS_Drawer::Draw_Top] = theColor;
aDrawer->myColor[NIS_Drawer::Draw_Transparent] = theColor;
SetDrawer (aDrawer);
}
//=======================================================================
//function : SetBackColor
//purpose : Set the normal color for presentation of back side of triangles.
//=======================================================================
void NIS_Surface::SetBackColor (const Quantity_Color& theColor)
{
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myBackColor = theColor;
SetDrawer (aDrawer);
}
//=======================================================================
//function : SetPolygonOffset
//purpose :
//=======================================================================
void NIS_Surface::SetPolygonOffset (const Standard_Real theValue)
{
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myPolygonOffset = static_cast<Standard_ShortReal>(theValue);
SetDrawer (aDrawer);
}
//=======================================================================
//function : SetDisplayMode
//purpose : Set the display mode: Shading or Wireframe.
//=======================================================================
void NIS_Surface::SetDisplayMode (const NIS_Surface::DisplayMode theMode)
{
Standard_Boolean isUpdate(Standard_False);
if (myIsWireframe) {
if (theMode != Wireframe) {
myIsWireframe = Standard_False;
isUpdate = Standard_True;
}
} else {
if (theMode == Wireframe) {
myIsWireframe = Standard_True;
isUpdate = Standard_True;
}
}
if (isUpdate && !GetDrawer().IsNull()) {
const Handle(NIS_SurfaceDrawer) aDrawer =
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
aDrawer->Assign (GetDrawer());
aDrawer->myIsWireframe = myIsWireframe;
SetDrawer(aDrawer);
}
}
//=======================================================================
//function : GetDisplayMode
//purpose : Query the current display mode: Shading or Wireframe.
//=======================================================================
NIS_Surface::DisplayMode NIS_Surface::GetDisplayMode () const
{
return myIsWireframe ? Wireframe : Shading;
}
//=======================================================================
//function : Clone
//purpose :
//=======================================================================
void NIS_Surface::Clone (const Handle_NCollection_BaseAllocator& theAlloc,
Handle_NIS_InteractiveObject& theDest) const
{
Handle(NIS_Surface) aNewObj;
if (theDest.IsNull()) {
aNewObj = new NIS_Surface(theAlloc);
theDest = aNewObj;
} else {
aNewObj = reinterpret_cast<NIS_Surface*> (theDest.operator->());
aNewObj->myAlloc = theAlloc;
}
NIS_InteractiveObject::Clone(theAlloc, theDest);
aNewObj->myNNodes = myNNodes;
if (myNNodes > 0) {
// copy nodes and normals
const Standard_Size nBytes = myNNodes*3*sizeof(Standard_ShortReal);
aNewObj->mypNodes = (Standard_ShortReal *)theAlloc->Allocate(nBytes);
aNewObj->mypNormals = (Standard_ShortReal *)theAlloc->Allocate(nBytes);
memcpy(aNewObj->mypNodes, mypNodes, nBytes);
memcpy(aNewObj->mypNormals, mypNormals, nBytes);
}
aNewObj->myNTriangles = myNTriangles;
if (myNTriangles > 0) {
const Standard_Size nBytes = sizeof(Standard_Integer) * 3 * myNTriangles;
aNewObj->mypTriangles = (Standard_Integer *)theAlloc->Allocate(nBytes);
memcpy(aNewObj->mypTriangles, mypTriangles, nBytes);
}
aNewObj->myNEdges = myNEdges;
if (myNEdges > 0) {
aNewObj->mypEdges = static_cast<Standard_Integer **>
(theAlloc->Allocate(sizeof(Standard_Integer *) * myNEdges));
for (Standard_Integer i = 0; i < myNEdges; i++) {
const Standard_Integer * pEdge = mypEdges[i];
const Standard_Size nBytes = sizeof(Standard_Integer) * (pEdge[0] + 1);
aNewObj->mypEdges[i] =
static_cast<Standard_Integer *> (theAlloc->Allocate(nBytes));
memcpy(aNewObj->mypEdges[i], pEdge, nBytes);
}
}
aNewObj->myIsWireframe = myIsWireframe;
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Real NIS_Surface::Intersect (const gp_Ax1& theAxis,
const Standard_Real theOver) const
{
Standard_Real aResult (RealLast());
Standard_Real start[3], dir[3];
theAxis.Location().Coord(start[0], start[1], start[2]);
theAxis.Direction().Coord(dir[0], dir[1], dir[2]);
double anInter;
if (myIsWireframe == Standard_False)
for (Standard_Integer i = 0; i < myNTriangles; i++) {
const Standard_Integer * pTri = &mypTriangles[3*i];
if (NIS_Triangulated::tri_line_intersect (start, dir,
&mypNodes[3*pTri[0]],
&mypNodes[3*pTri[1]],
&mypNodes[3*pTri[2]],
&anInter))
if (anInter < aResult)
aResult = anInter;
}
else {
const Standard_Real anOver2 = theOver*theOver;
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
const Standard_Integer * anEdge = mypEdges[iEdge];
const Standard_Integer nNodes = anEdge[0];
for (Standard_Integer i = 1; i < nNodes; i++) {
// Node index is incremented for the head of polygon indice array
if (NIS_Triangulated::seg_line_intersect (theAxis.Location().XYZ(),
theAxis.Direction().XYZ(),
anOver2,
&mypNodes[3*anEdge[i+0]],
&mypNodes[3*anEdge[i+1]],
&anInter))
if (anInter < aResult)
aResult = anInter;
}
}
}
return aResult;
}
//=======================================================================
//function : Intersect
//purpose :
//=======================================================================
Standard_Boolean NIS_Surface::Intersect (const Bnd_B3f& theBox,
const gp_Trsf& theTrf,
const Standard_Boolean isFullIn) const
{
Standard_Boolean aResult (isFullIn);
if (myIsWireframe == Standard_False) {
if (myNTriangles > 0) {
for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
static_cast<Standard_Real>(mypNodes[iNode+1]),
static_cast<Standard_Real>(mypNodes[iNode+2]));
theTrf.Transforms(aPnt);
if (theBox.IsOut (aPnt) == isFullIn) {
aResult = !isFullIn;
break;
}
}
}
} else {
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
const Standard_Integer * anEdge = mypEdges[iEdge];
const Standard_Integer nNodes = anEdge[0];
for (Standard_Integer i = 1; i < nNodes; i++) {
// index is incremented by 1 for the head number in the array
gp_Pnt aPnt[2] = {
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
};
aPnt[0].Transform(theTrf);
aPnt[1].Transform(theTrf);
if (isFullIn) {
if (NIS_Triangulated::seg_box_included (theBox, aPnt) == 0) {
aResult = Standard_False;
break;
}
} else {
if (NIS_Triangulated::seg_box_intersect (theBox, aPnt)) {
aResult = Standard_True;
break;
}
}
}
}
}
return aResult;
}
//=======================================================================
//function : Intersect
//purpose : Selection by polygon
//=======================================================================
Standard_Boolean NIS_Surface::Intersect
(const NCollection_List<gp_XY> &thePolygon,
const gp_Trsf &theTrf,
const Standard_Boolean isFullIn) const
{
Standard_Boolean aResult (isFullIn);
if (myIsWireframe == Standard_False) {
if (myNTriangles > 0) {
for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
static_cast<Standard_Real>(mypNodes[iNode+1]),
static_cast<Standard_Real>(mypNodes[iNode+2]));
theTrf.Transforms(aPnt);
gp_XY aP2d(aPnt.X(), aPnt.Y());
if (!NIS_Triangulated::IsIn(thePolygon, aP2d)) {
if (isFullIn) {
aResult = Standard_False;
break;
}
} else {
if (isFullIn == Standard_False) {
aResult = Standard_True;
break;
}
}
}
}
} else {
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
const Standard_Integer * anEdge = mypEdges[iEdge];
const Standard_Integer nNodes = anEdge[0];
for (Standard_Integer i = 1; i < nNodes; i++) {
// index is incremented by 1 for the head number in the array
gp_Pnt aPnt[2] = {
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
};
aPnt[0].Transform(theTrf);
aPnt[1].Transform(theTrf);
const gp_XY aP2d[2] = { gp_XY(aPnt[0].X(), aPnt[0].Y()),
gp_XY(aPnt[1].X(), aPnt[1].Y()) };
if (isFullIn) {
if (NIS_Triangulated::seg_polygon_included (thePolygon, aP2d) == 0) {
aResult = Standard_False;
break;
}
} else {
if (NIS_Triangulated::seg_polygon_intersect (thePolygon, aP2d)) {
aResult = Standard_True;
break;
}
}
}
}
}
return aResult;
}
//=======================================================================
//function : computeBox
//purpose :
//=======================================================================
void NIS_Surface::computeBox ()
{
NIS_Triangulated::ComputeBox(myBox, myNNodes, mypNodes, 3);
const Handle(NIS_SurfaceDrawer)& aDrawer =
static_cast<const Handle(NIS_SurfaceDrawer)&> (GetDrawer());
if (aDrawer.IsNull() == Standard_False) {
const gp_Trsf& aTrsf = aDrawer->GetTransformation();
myBox = myBox.Transformed(aTrsf);
}
}