Esempio n. 1
0
gp_Vec normalToFaceAtUV(const TopoDS_Face& face, double u, double v)
{
  BRepLProp_SLProps localSurfaceProps(1, 1e-6);
  localSurfaceProps.SetSurface(BRepAdaptor_Surface(face));
  localSurfaceProps.SetParameters(u, v);
  if (localSurfaceProps.IsNormalDefined()) {
    const gp_Dir& nc = localSurfaceProps.Normal();
    if (face.Orientation() == TopAbs_REVERSED)
      return gp_Vec(-nc.X(), -nc.Y(), -nc.Z());
    else
      return gp_Vec(nc.X(), nc.Y(), nc.Z());
  }
  return gp_Vec(0., 0., 1.);
  //return normalToSurfaceAtUV(BRep_Tool::Surface(face), u, v);
}
int convert_to_ifc(const TopoDS_Face& f, IfcSchema::IfcFace*& face, bool advanced) {
	Handle_Geom_Surface surf = BRep_Tool::Surface(f);
	TopExp_Explorer exp(f, TopAbs_WIRE);
	IfcSchema::IfcFaceBound::list::ptr bounds(new IfcSchema::IfcFaceBound::list);
	int index = 0;
	for (; exp.More(); exp.Next(), ++index) {
		IfcSchema::IfcLoop* loop;
		if (!convert_to_ifc(TopoDS::Wire(exp.Current()), loop, advanced)) {
			return 0;
		}
		IfcSchema::IfcFaceBound* bnd;
		if (index == 0) {
			bnd = new IfcSchema::IfcFaceOuterBound(loop, true);
		} else {
			bnd = new IfcSchema::IfcFaceBound(loop, true);
		}
		bounds->push(bnd);
	}

	const bool is_planar = surf->DynamicType() == STANDARD_TYPE(Geom_Plane);

	if (!is_planar && !advanced) {
		return 0;
	}
	if (is_planar && !advanced) {
		face = new IfcSchema::IfcFace(bounds);
		return 1;
	} else {
#ifdef USE_IFC4
		IfcSchema::IfcSurface* surface;
		if (!convert_to_ifc(surf, surface, advanced)) {
			return 0;
		}
		face = new IfcSchema::IfcAdvancedFace(bounds, surface, f.Orientation() == TopAbs_FORWARD);
		return 1;
#else
		// No IfcAdvancedFace in Ifc2x3
		return 0;
#endif
	}
}
bool SMESH_Algo::IsReversedSubMesh (const TopoDS_Face&  theFace,
                                    SMESHDS_Mesh*       theMeshDS)
{
  if ( theFace.IsNull() || !theMeshDS )
    return false;

  // find out orientation of a meshed face
  int faceID = theMeshDS->ShapeToIndex( theFace );
  TopoDS_Shape aMeshedFace = theMeshDS->IndexToShape( faceID );
  bool isReversed = ( theFace.Orientation() != aMeshedFace.Orientation() );

  const SMESHDS_SubMesh * aSubMeshDSFace = theMeshDS->MeshElements( faceID );
  if ( !aSubMeshDSFace )
    return isReversed;

  // find element with node located on face and get its normal
  const SMDS_FacePosition* facePos = 0;
  int vertexID = 0;
  gp_Pnt nPnt[3];
  gp_Vec Ne;
  bool normalOK = false;
  SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
  while ( iteratorElem->more() ) // loop on elements on theFace
  {
    const SMDS_MeshElement* elem = iteratorElem->next();
    if ( elem && elem->NbNodes() > 2 ) {
      SMDS_ElemIteratorPtr nodesIt = elem->nodesIterator();
      const SMDS_FacePosition* fPos = 0;
      int i = 0, vID = 0;
      while ( nodesIt->more() ) { // loop on nodes
        const SMDS_MeshNode* node
          = static_cast<const SMDS_MeshNode *>(nodesIt->next());
        if ( i == 3 ) i = 2;
        nPnt[ i++ ].SetCoord( node->X(), node->Y(), node->Z() );
        // check position
        const SMDS_PositionPtr& pos = node->GetPosition();
        if ( !pos ) continue;
        if ( pos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
          fPos = dynamic_cast< const SMDS_FacePosition* >( pos.get() );
        }
        else if ( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) {
          vID = pos->GetShapeId();
        }
      }
      if ( fPos || ( !normalOK && vID )) {
        // compute normal
        gp_Vec v01( nPnt[0], nPnt[1] ), v02( nPnt[0], nPnt[2] );
        if ( v01.SquareMagnitude() > RealSmall() &&
             v02.SquareMagnitude() > RealSmall() )
        {
          Ne = v01 ^ v02;
          normalOK = ( Ne.SquareMagnitude() > RealSmall() );
        }
        // we need position on theFace or at least on vertex
        if ( normalOK ) {
          vertexID = vID;
          if ((facePos = fPos))
            break;
        }
      }
    }
  }
  if ( !normalOK )
    return isReversed;

  // node position on face
  double u,v;
  if ( facePos ) {
    u = facePos->GetUParameter();
    v = facePos->GetVParameter();
  }
  else if ( vertexID ) {
    TopoDS_Shape V = theMeshDS->IndexToShape( vertexID );
    if ( V.IsNull() || V.ShapeType() != TopAbs_VERTEX )
      return isReversed;
    gp_Pnt2d uv = BRep_Tool::Parameters( TopoDS::Vertex( V ), theFace );
    u = uv.X();
    v = uv.Y();
  }
  else
  {
    return isReversed;
  }

  // face normal at node position
  TopLoc_Location loc;
  Handle(Geom_Surface) surf = BRep_Tool::Surface( theFace, loc );
  if ( surf.IsNull() || surf->Continuity() < GeomAbs_C1 ) return isReversed;
  gp_Vec d1u, d1v;
  surf->D1( u, v, nPnt[0], d1u, d1v );
  gp_Vec Nf = (d1u ^ d1v).Transformed( loc );

  if ( theFace.Orientation() == TopAbs_REVERSED )
    Nf.Reverse();

  return Ne * Nf < 0.;
}
Esempio n. 4
0
   void VisualSceneOCCGeometry :: BuildScene (int zoomall)
   {
     if (occgeometry -> changed == OCCGEOMETRYVISUALIZATIONFULLCHANGE)
       {
         occgeometry -> BuildVisualizationMesh (vispar.occdeflection);

         center = occgeometry -> Center();
         rad = occgeometry -> GetBoundingBox().Diam() / 2;

         if (vispar.occzoomtohighlightedentity)
         {
            bool hilite = false;
            bool hiliteonepoint = false;
            Bnd_Box bb;

            for (int i = 1; i <= occgeometry->fmap.Extent(); i++)
            if (occgeometry->fvispar[i-1].IsHighlighted())
            {
               hilite = true;
               BRepBndLib::Add (occgeometry->fmap(i), bb);
            }

            for (int i = 1; i <= occgeometry->emap.Extent(); i++)
            if (occgeometry->evispar[i-1].IsHighlighted())
            {
               hilite = true;
               BRepBndLib::Add (occgeometry->emap(i), bb);
            }

            for (int i = 1; i <= occgeometry->vmap.Extent(); i++)
            if (occgeometry->vvispar[i-1].IsHighlighted())
            {
               hiliteonepoint = true;
               BRepBndLib::Add (occgeometry->vmap(i), bb);
            }

            if (hilite || hiliteonepoint)
            {
               double x1,y1,z1,x2,y2,z2;
               bb.Get (x1,y1,z1,x2,y2,z2);
               Point<3> p1 = Point<3> (x1,y1,z1);
               Point<3> p2 = Point<3> (x2,y2,z2);
               Box<3> boundingbox(p1,p2);

               center = boundingbox.Center();
               if (hiliteonepoint)
               rad = occgeometry -> GetBoundingBox().Diam() / 100;
               else
               rad = boundingbox.Diam() / 2;
            }
         }

         CalcTransformationMatrices();
      }

      // Clear lists

      for (int i = 1; i <= linelists.Size(); i++)
      glDeleteLists (linelists.Elem(i), 1);
      linelists.SetSize(0);

      for (int i = 1; i <= trilists.Size(); i++)
      glDeleteLists (trilists.Elem(i), 1);
      trilists.SetSize(0);

      // Total wireframe

      linelists.Append (glGenLists (1));
      glNewList (linelists.Last(), GL_COMPILE);

      for (int i = 1; i <= occgeometry->emap.Extent(); i++)
      {
         TopoDS_Edge edge = TopoDS::Edge(occgeometry->emap(i));
         if (BRep_Tool::Degenerated(edge)) continue;
         if (occgeometry->evispar[i-1].IsHighlighted()) continue;

         Handle(Poly_PolygonOnTriangulation) aEdgePoly;
         Handle(Poly_Triangulation) T;
         TopLoc_Location aEdgeLoc;
         BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc);

         if(aEdgePoly.IsNull())
         {
            (*testout) << "visualizing edge " << occgeometry->emap.FindIndex (edge)
            << " without using the occ visualization triangulation" << endl;

            double s0, s1;
            Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1);

            glBegin (GL_LINE_STRIP);
            for (int i = 0; i<=50; i++)
            {
               gp_Pnt p = c->Value (s0 + i*(s1-s0)/50.0);
               glVertex3f (p.X(),p.Y(),p.Z());
            }
            glEnd ();

            continue;
         }

         int nbnodes = aEdgePoly -> NbNodes();
         glBegin (GL_LINE_STRIP);
         for (int j = 1; j <= nbnodes; j++)
         {
            gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc);
            glVertex3f (p.X(), p.Y(), p.Z());
         }
         glEnd ();
      }

      glEndList ();

      // Highlighted edge list

      linelists.Append (glGenLists (1));
      glNewList (linelists.Last(), GL_COMPILE);

      for (int i = 1; i <= occgeometry->emap.Extent(); i++)
      if (occgeometry->evispar[i-1].IsHighlighted())
      {
         TopoDS_Edge edge = TopoDS::Edge(occgeometry->emap(i));
         if (BRep_Tool::Degenerated(edge)) continue;

         Handle(Poly_PolygonOnTriangulation) aEdgePoly;
         Handle(Poly_Triangulation) T;
         TopLoc_Location aEdgeLoc;
         BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc);

         if(aEdgePoly.IsNull())
         {
            (*testout) << "visualizing edge " << occgeometry->emap.FindIndex (edge)
            << " without using the occ visualization triangulation" << endl;

            double s0, s1;
            Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1);

            glBegin (GL_LINE_STRIP);
            for (int i = 0; i<=50; i++)
            {
               gp_Pnt p = c->Value (s0 + i*(s1-s0)/50.0);
               glVertex3f (p.X(),p.Y(),p.Z());
            }
            glEnd ();

            continue;
         }

         int nbnodes = aEdgePoly -> NbNodes();
         glBegin (GL_LINE_STRIP);
         for (int j = 1; j <= nbnodes; j++)
         {
            gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc);
            glVertex3f (p.X(), p.Y(), p.Z());
         }
         glEnd ();
      }

      glEndList ();

      // display faces

      trilists.Append (glGenLists (1));
      glNewList (trilists.Last(), GL_COMPILE);

      for (int i = 1; i <= occgeometry->fmap.Extent(); i++)
      {
         if (!occgeometry->fvispar[i-1].IsVisible()) continue;

         glLoadName (i);
         float mat_col[4];
         mat_col[3] = 1;

         TopoDS_Face face = TopoDS::Face(occgeometry->fmap(i));

         if (!occgeometry->fvispar[i-1].IsHighlighted())
         {
            // Philippose - 30/01/2009
            // OpenCascade XDE Support
            Quantity_Color face_colour;
            // Philippose - 23/02/2009
            // Check to see if colours have been extracted first!!
            // Forum bug-fox (Jean-Yves - 23/02/2009)
            if(!(occgeometry->face_colours.IsNull())
               && (occgeometry->face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour)))
            {
               mat_col[0] = face_colour.Red();
               mat_col[1] = face_colour.Green();
               mat_col[2] = face_colour.Blue();
            }
            else
            {
               mat_col[0] = 0.0;
               mat_col[1] = 1.0;
               mat_col[2] = 0.0;
            }
         }
         else
         {
            mat_col[0] = 0.8;
            mat_col[1] = 0.2;
            mat_col[2] = 0.2;
         }

         glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col);

         TopLoc_Location loc;
         Handle(Geom_Surface) surf = BRep_Tool::Surface (face);
         BRepAdaptor_Surface sf(face, Standard_False);
         BRepLProp_SLProps prop(sf, 1, 1e-5);
         Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc);

         if (triangulation.IsNull())
         {
            cout << "cannot visualize face " << i << endl;
            occgeometry->fvispar[i-1].SetNotDrawable();
            continue;
         }

         gp_Pnt2d uv;
         gp_Pnt pnt;
         gp_Vec n;

         glBegin (GL_TRIANGLES);

         int ntriangles = triangulation -> NbTriangles();
         for (int j = 1; j <= ntriangles; j++)
         {
            Poly_Triangle triangle = (triangulation -> Triangles())(j);
            gp_Pnt p[3];
            for (int k = 1; k <= 3; k++)
            p[k-1] = (triangulation -> Nodes())(triangle(k)).Transformed(loc);

            for (int k = 1; k <= 3; k++)
            {
               uv = (triangulation -> UVNodes())(triangle(k));
               prop.SetParameters (uv.X(), uv.Y());

               //	      surf->D0 (uv.X(), uv.Y(), pnt);

               if (prop.IsNormalDefined())
               n = prop.Normal();
               else
               {
                  (*testout) << "Visualization of face " << i
                  << ": Normal vector not defined" << endl;
                  //		  n = gp_Vec (0,0,0);
                  gp_Vec a(p[0],p[1]);
                  gp_Vec b(p[0],p[2]);
                  n = b^a;
               }

               if (face.Orientation() == TopAbs_REVERSED) n *= -1;
               glNormal3f (n.X(), n.Y(), n.Z());
               glVertex3f (p[k-1].X(), p[k-1].Y(), p[k-1].Z());
            }
         }
         glEnd ();

      }
      glEndList ();

   }
Esempio n. 5
0
void ShapeGeometryBuilder::faceConstruct(const TopoDS_Face &faceIn)
{
  TopLoc_Location location;
  Handle(Poly_Triangulation) triangulation;
  triangulation = BRep_Tool::Triangulation(faceIn, location);

  if (triangulation.IsNull())
      throw std::runtime_error("null triangulation in face construction");

  bool signalOrientation(false);
  if (faceIn.Orientation() == TopAbs_FORWARD)
      signalOrientation = true;

  gp_Trsf transformation;
  bool identity = true;
  if(!location.IsIdentity())
  {
    identity = false;
    transformation = location.Transformation();
  }

  //vertices.
  const TColgp_Array1OfPnt& nodes = triangulation->Nodes();
  osg::Vec3Array *vertices = dynamic_cast<osg::Vec3Array *>(faceGeometry->getVertexArray());
  osg::Vec3Array *normals = dynamic_cast<osg::Vec3Array *>(faceGeometry->getNormalArray());
  osg::Vec4Array *colors = dynamic_cast<osg::Vec4Array *>(faceGeometry->getColorArray());
  std::size_t offset = vertices->size();
  for (int index(nodes.Lower()); index < nodes.Upper() + 1; ++index)
  {
    gp_Pnt point = nodes.Value(index);
    if(!identity)
	point.Transform(transformation);
    vertices->push_back(osg::Vec3(point.X(), point.Y(), point.Z()));
    normals->push_back(osg::Vec3(0.0, 0.0, 0.0));
    colors->push_back(faceGeometry->getColor());
  }

  const Poly_Array1OfTriangle& triangles = triangulation->Triangles();
  osg::ref_ptr<osg::DrawElementsUInt> indices = new osg::DrawElementsUInt
	  (GL_TRIANGLES, triangulation->NbTriangles() * 3);

  for (int index(triangles.Lower()); index < triangles.Upper() + 1; ++index)
  {
    int N1, N2, N3;
    triangles(index).Get(N1, N2, N3);

    int factor = (index - 1) * 3;
    if (!signalOrientation)
    {
      (*indices)[factor] = N3 - 1  + offset;
      (*indices)[factor + 1] = N2 - 1 + offset;
      (*indices)[factor + 2] = N1 - 1 + offset;
    }
    else
    {
      (*indices)[factor] = N1 - 1 + offset;
      (*indices)[factor + 1] = N2 - 1 + offset;
      (*indices)[factor + 2] = N3 - 1 + offset;
    }
    
    //store primitiveset index and vertex indes into map.
    PSetVertexRecord record;
    record.primitiveSetIndex = faceGeometry->getNumPrimitiveSets();
    
    record.vertexIndex = (*indices)[factor];
    pSetTriangleWrapper->pSetVertexContainer.insert(record);
    
    record.vertexIndex = (*indices)[factor + 1];
    pSetTriangleWrapper->pSetVertexContainer.insert(record);
    
    record.vertexIndex = (*indices)[factor + 2];
    pSetTriangleWrapper->pSetVertexContainer.insert(record);
    
    //now that we are combining faces into one geometry, osgUtil SmoothingVisitor
    //wants to 'average' out normals across faces. so we go back to manual calculation
    //of surface normals.

    osg::Vec3 pointOne(vertices->at((*indices)[factor]));
    osg::Vec3 pointTwo(vertices->at((*indices)[factor + 1]));
    osg::Vec3 pointThree(vertices->at((*indices)[factor + 2]));

    osg::Vec3 axisOne(pointTwo - pointOne);
    osg::Vec3 axisTwo(pointThree - pointOne);
    osg::Vec3 currentNormal(axisOne ^ axisTwo);
    if (currentNormal.isNaN())
	continue;
    currentNormal.normalize();

    osg::Vec3 tempNormal;

    tempNormal = (*normals)[(*indices)[factor]];
    tempNormal += currentNormal;
    tempNormal.normalize();
    (*normals)[(*indices)[factor]] = tempNormal;

    tempNormal = (*normals)[(*indices)[factor + 1]];
    tempNormal += currentNormal;
    tempNormal.normalize();
    (*normals)[(*indices)[factor + 1]] = tempNormal;

    tempNormal = (*normals)[(*indices)[factor + 2]];
    tempNormal += currentNormal;
    tempNormal.normalize();
    (*normals)[(*indices)[factor + 2]] = tempNormal;
  }
  faceGeometry->addPrimitiveSet(indices.get());
  boost::uuids::uuid id = seerShape->findShapeIdRecord(faceIn).id;
  std::size_t lastPrimitiveIndex = faceGeometry->getNumPrimitiveSets() - 1;
  if (!idPSetWrapperFace->hasId(id))
  {
    IdPSetRecord record;
    record.id = id;
    record.primitiveSetIndex = lastPrimitiveIndex;
    idPSetWrapperFace->idPSetContainer.insert(record);
  }
  else
    //ensure that the faces have the same primitive index between lod calls.
    assert(lastPrimitiveIndex == idPSetWrapperFace->findPSetFromId(id));
}
//=======================================================================
// function: BuildSplitFaces
// purpose:
//=======================================================================
void GEOMAlgo_Builder::BuildSplitFaces()
{
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  NMTDS_InterfPool* pIP=pPF->IP();
  BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  Standard_Boolean bToReverse, bIsClosed, bIsDegenerated;
  Standard_Integer i, aNb, aNbF, nF;
  TopTools_MapOfShape aMFence;
  TColStd_IndexedMapOfInteger aMFP;
  TopExp_Explorer anExp;
  TopoDS_Face aFF;
  TopoDS_Edge aSp, aEE;
  TopTools_ListIteratorOfListOfShape aIt;
  TopAbs_Orientation anOriF, anOriE;
  //
  mySplitFaces.Clear();
  //
  // 1. Select Faces to process (MFP)
  aNb=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNb; ++i) {
    const TopoDS_Shape& aF=aDS.Shape(i);
    if (aF.ShapeType()!=TopAbs_FACE) {
      continue;
    }
    if (!aMFence.Add(aF)) {
      continue;
    }
    //
    if (myInParts.Contains(aF)) {
      aMFP.Add(i);
      continue;
    }
    //
    anExp.Init(aF, TopAbs_EDGE);
    for (; anExp.More(); anExp.Next()) {
      const TopoDS_Shape& aE=anExp.Current();
      if (myImages.HasImage(aE)) {
        aMFP.Add(i);
        break;
      }
    }
    //
    //===
    {
      Standard_Integer aNbFFs, aNbSE, j, n1, n2;
      //
      aNbFFs=aFFs.Extent();
      for (j=1; j<=aNbFFs; ++j) {
        BOPTools_SSInterference& aFFj=aFFs(j);
        aFFj.Indices(n1, n2);
        if (!(n1==i || n2==i)) {
          continue;
        }
        //
        const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges();
        aNbSE=aLSE.Extent();
        if (aNbSE) {
          aMFP.Add(i);
          break;
        }
      }
    }
    //===
    //
  }// for (i=1; i<=aNb; ++i)
  //
  // 2. ProcessFaces
  aNbF=aMFP.Extent();
  for (i=1; i<=aNbF; ++i) {
    nF=aMFP(i);
    const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF));
    anOriF=aF.Orientation();
    aFF=aF;
    aFF.Orientation(TopAbs_FORWARD);
    //
    aMFence.Clear();
    //
    // 2.1. Fill WES
    GEOMAlgo_WireEdgeSet aWES;
    aWES.SetFace(aFF);
    //
    //  2.1.1. Add Split parts
    anExp.Init(aFF, TopAbs_EDGE);
    for (; anExp.More(); anExp.Next()) {
      const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
      anOriE=aE.Orientation();
      //
      if (!myImages.HasImage(aE)) {
        if (anOriE==TopAbs_INTERNAL) {
          aEE=aE;
          aEE.Orientation(TopAbs_FORWARD);
          aWES.AddStartElement(aEE);
          aEE.Orientation(TopAbs_REVERSED);
          aWES.AddStartElement(aEE);
        }
        else {
          aWES.AddStartElement(aE);
        }
        continue;
      }
      //
      bIsDegenerated=BRep_Tool::Degenerated(aE);
      //modified by NIZNHY-PKV Wed Mar 07 07:46:09 2012f
      bIsClosed=IsClosed(aE, aF);
      //bIsClosed=BRep_Tool::IsClosed(aE, aF);
      //modified by NIZNHY-PKV Wed Mar 07 07:46:13 2012t
      //
      const TopTools_ListOfShape& aLIE=myImages.Image(aE);
      aIt.Initialize(aLIE);
      for (; aIt.More(); aIt.Next()) {
        aSp=TopoDS::Edge(aIt.Value());
        //
        if (bIsDegenerated) {
          aSp.Orientation(anOriE);
          aWES.AddStartElement(aSp);
          continue;
        }
        //
        if (anOriE==TopAbs_INTERNAL) {
          aSp.Orientation(TopAbs_FORWARD);
          aWES.AddStartElement(aSp);
          aSp.Orientation(TopAbs_REVERSED);
          aWES.AddStartElement(aSp);
          continue;
        }
        //
        if (bIsClosed){
          if (aMFence.Add(aSp)) {
            //
            if (!BRep_Tool::IsClosed(aSp, aF)){
              BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
            }
            //
            aSp.Orientation(TopAbs_FORWARD);
            aWES.AddStartElement(aSp);
            aSp.Orientation(TopAbs_REVERSED);
            aWES.AddStartElement(aSp);
          }
          continue;
        }// if (aMFence.Add(aSp))
        //
        aSp.Orientation(anOriE);
        bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
        if (bToReverse) {
          aSp.Reverse();
        }
        aWES.AddStartElement(aSp);
      }// for (; aIt.More(); aIt.Next()) {
    }// for (; anExp.More(); anExp.Next()) {
    //
    // 2.1.2. Add In2D Parts
    if (myInParts.Contains(aF)) {
      const TopTools_ListOfShape& aLE=myInParts.FindFromKey(aF);
      aIt.Initialize(aLE);
      for (; aIt.More(); aIt.Next()) {
        aSp=TopoDS::Edge(aIt.Value());
        //
        aSp.Orientation(TopAbs_FORWARD);
        aWES.AddStartElement(aSp);
        //
        aSp.Orientation(TopAbs_REVERSED);
        aWES.AddStartElement(aSp);
      }
    }
    //
    // 2.2. Build images Faces
    TopTools_ListOfShape aLFR;
    GEOMAlgo_ShapeSet aS1, aS2;
    //
    const TopTools_ListOfShape& aSE=aWES.StartElements();
    aS1.Add(aSE);
    aS2.Add(aFF, TopAbs_EDGE);
    if (aS1.IsEqual(aS2)) {
      aLFR.Append(aF);
    }
    else {
      GEOMAlgo_BuilderFace aBF;
      //
      aBF.SetFace(aFF);
      aBF.SetContext(aCtx);
      aBF.SetShapes(aSE);
      // <-DEB
      aBF.Perform();
      //
      const TopTools_ListOfShape& aLF=aBF.Areas();
      aIt.Initialize(aLF);
      for (; aIt.More(); aIt.Next()) {
        TopoDS_Shape& aFR=aIt.Value();
        if (anOriF==TopAbs_REVERSED) {
          aFR.Orientation(TopAbs_REVERSED);
        }
        aLFR.Append(aFR);
      }
    }
    //
    // 2.3. Collect draft images Faces
    mySplitFaces.Bind(aF, aLFR);
  }//for (i=1; i<=aNbF; ++i)
}
Esempio n. 7
0
void PovTools::transferToArray(const TopoDS_Face& aFace,gp_Vec** vertices,gp_Vec** vertexnormals, long** cons,int &nbNodesInFace,int &nbTriInFace )
{
    TopLoc_Location aLoc;

    // doing the meshing and checking the result
    //BRepMesh_IncrementalMesh MESH(aFace,fDeflection);
    Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
    if (aPoly.IsNull()) {
        Base::Console().Log("Empty face trianglutaion\n");
        nbNodesInFace =0;
        nbTriInFace = 0;
        vertices = 0l;
        cons = 0l;
        return;
    }

    // getting the transformation of the shape/face
    gp_Trsf myTransf;
    Standard_Boolean identity = true;
    if (!aLoc.IsIdentity())  {
        identity = false;
        myTransf = aLoc.Transformation();
    }

    Standard_Integer i;
    // getting size and create the array
    nbNodesInFace = aPoly->NbNodes();
    nbTriInFace = aPoly->NbTriangles();
    *vertices = new gp_Vec[nbNodesInFace];
    *vertexnormals = new gp_Vec[nbNodesInFace];
    for (i=0; i < nbNodesInFace; i++) {
        (*vertexnormals)[i]= gp_Vec(0.0,0.0,0.0);
    }

    *cons = new long[3*(nbTriInFace)+1];

    // check orientation
    TopAbs_Orientation orient = aFace.Orientation();

    // cycling through the poly mesh
    const Poly_Array1OfTriangle& Triangles = aPoly->Triangles();
    const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
    for (i=1; i<=nbTriInFace; i++) {
        // Get the triangle
        Standard_Integer N1,N2,N3;
        Triangles(i).Get(N1,N2,N3);

        // change orientation of the triangles
        if ( orient != TopAbs_FORWARD )
        {
            Standard_Integer tmp = N1;
            N1 = N2;
            N2 = tmp;
        }

        gp_Pnt V1 = Nodes(N1);
        gp_Pnt V2 = Nodes(N2);
        gp_Pnt V3 = Nodes(N3);

        // transform the vertices to the place of the face
        if (!identity) {
            V1.Transform(myTransf);
            V2.Transform(myTransf);
            V3.Transform(myTransf);
        }

        // Calculate triangle normal
        gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z());
        gp_Vec Normal = (v2-v1)^(v3-v1);

        //Standard_Real Area = 0.5 * Normal.Magnitude();

        // add the triangle normal to the vertex normal for all points of this triangle
        (*vertexnormals)[N1-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());
        (*vertexnormals)[N2-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());
        (*vertexnormals)[N3-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());

        (*vertices)[N1-1].SetX((float)(V1.X()));
        (*vertices)[N1-1].SetY((float)(V1.Y()));
        (*vertices)[N1-1].SetZ((float)(V1.Z()));
        (*vertices)[N2-1].SetX((float)(V2.X()));
        (*vertices)[N2-1].SetY((float)(V2.Y()));
        (*vertices)[N2-1].SetZ((float)(V2.Z()));
        (*vertices)[N3-1].SetX((float)(V3.X()));
        (*vertices)[N3-1].SetY((float)(V3.Y()));
        (*vertices)[N3-1].SetZ((float)(V3.Z()));

        int j = i - 1;
        N1--;
        N2--;
        N3--;
        (*cons)[3*j] = N1;
        (*cons)[3*j+1] = N2;
        (*cons)[3*j+2] = N3;
    }

    // normalize all vertex normals
    for (i=0; i < nbNodesInFace; i++) {

        gp_Dir clNormal;

        try {
            Handle(Geom_Surface) Surface = BRep_Tool::Surface(aFace);

            gp_Pnt vertex((*vertices)[i].XYZ());
//     gp_Pnt vertex((*vertices)[i][0], (*vertices)[i][1], (*vertices)[i][2]);
            GeomAPI_ProjectPointOnSurf ProPntSrf(vertex, Surface);
            Standard_Real fU, fV;
            ProPntSrf.Parameters(1, fU, fV);

            GeomLProp_SLProps clPropOfFace(Surface, fU, fV, 2, gp::Resolution());

            clNormal = clPropOfFace.Normal();
            gp_Vec temp = clNormal;
            //Base::Console().Log("unterschied:%.2f",temp.dot((*vertexnormals)[i]));
            if ( temp * (*vertexnormals)[i] < 0 )
                temp = -temp;
            (*vertexnormals)[i] = temp;

        }
        catch (...) {
        }

        (*vertexnormals)[i].Normalize();
    }
}
void BuildMesh(osg::Geode *geode, const TopoDS_Face &face, const osg::Vec4 &color, double deflection)
{
	osg::ref_ptr<deprecated_osg::Geometry> triGeom = new deprecated_osg::Geometry();
	osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array();

	TopLoc_Location location;
	BRepMesh::Mesh(face, deflection);

	const Handle_Poly_Triangulation &triFace = BRep_Tool::Triangulation(face, location);

	Standard_Integer nTriangles = triFace->NbTriangles();

	gp_Pnt vertex1;
	gp_Pnt vertex2;
	gp_Pnt vertex3;

	Standard_Integer nVertexIndex1 = 0;
	Standard_Integer nVertexIndex2 = 0;
	Standard_Integer nVertexIndex3 = 0;

	const TColgp_Array1OfPnt &nodes = triFace->Nodes();
	const Poly_Array1OfTriangle &triangles = triFace->Triangles();

	for (Standard_Integer i = 1; i <= nTriangles; i++)
	{
		const Poly_Triangle &aTriangle = triangles.Value(i);

		aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);

		vertex1 = nodes.Value(nVertexIndex1).Transformed(location.Transformation());
		vertex2 = nodes.Value(nVertexIndex2).Transformed(location.Transformation());
		vertex3 = nodes.Value(nVertexIndex3).Transformed(location.Transformation());

		gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ());
		gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ());
		gp_XYZ normal = vector12.Crossed(vector13);
		Standard_Real rModulus = normal.Modulus();

		if (rModulus > gp::Resolution())
		{
			normal.Normalize();
		}
		else
		{
			normal.SetCoord(0., 0., 0.);
		}

		if (face.Orientation() != TopAbs_FORWARD)
		{
		    normal.Reverse();
		}

		vertices->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()));
		vertices->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()));
		vertices->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()));

		normals->push_back(osg::Vec3(normal.X(), normal.Y(), normal.Z()));
	}

	triGeom->setVertexArray(vertices);
	triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size()));

	triGeom->setNormalArray(normals);
	triGeom->setNormalBinding(deprecated_osg::Geometry::BIND_PER_PRIMITIVE);

	osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array();
	colArr->push_back(color);
	triGeom->setColorArray(colArr, osg::Array::BIND_OVERALL);

	geode->addDrawable(triGeom);
}
void BuildShapeMesh(osg::Geode *geode, const TopoDS_Shape &shape, const osg::Vec4 &color, double deflection)
{
	bool bSetNormal = true;
	osg::ref_ptr<deprecated_osg::Geometry> triGeom = new deprecated_osg::Geometry();
	osg::ref_ptr<osg::Vec3Array> theVertices = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec3Array> theNormals = new osg::Vec3Array();

	BRepMesh::Mesh(shape, deflection);

	TopExp_Explorer faceExplorer;
	for (faceExplorer.Init(shape, TopAbs_FACE); faceExplorer.More(); faceExplorer.Next())
	{
		TopLoc_Location theLocation;
		TopoDS_Face theFace = TopoDS::Face(faceExplorer.Current());
	
		if (theFace.IsNull())
			continue;

		const Handle_Poly_Triangulation &theTriangulation = BRep_Tool::Triangulation(theFace, theLocation);
		BRepLProp_SLProps theProp(BRepAdaptor_Surface(theFace), 1, Precision::Confusion());
	
		Standard_Integer nTriangles = theTriangulation->NbTriangles();
	
		for (Standard_Integer i = 1; i <= nTriangles; i++)
		{
			const Poly_Triangle& theTriangle = theTriangulation->Triangles().Value(i);
			gp_Pnt theVertex1 = theTriangulation->Nodes().Value(theTriangle(1));
			gp_Pnt theVertex2 = theTriangulation->Nodes().Value(theTriangle(2));
			gp_Pnt theVertex3 = theTriangulation->Nodes().Value(theTriangle(3));

			const gp_Pnt2d &theUV1 = theTriangulation->UVNodes().Value(theTriangle(1));
			const gp_Pnt2d &theUV2 = theTriangulation->UVNodes().Value(theTriangle(2));
			const gp_Pnt2d &theUV3 = theTriangulation->UVNodes().Value(theTriangle(3));

			theVertex1.Transform(theLocation.Transformation());
			theVertex2.Transform(theLocation.Transformation());
			theVertex3.Transform(theLocation.Transformation());

			// find the normal for the triangle mesh.
			gp_Vec V12(theVertex1, theVertex2);
			gp_Vec V13(theVertex1, theVertex3);
			gp_Vec theNormal = V12 ^ V13;
			gp_Vec theNormal1 = theNormal;
			gp_Vec theNormal2 = theNormal;
			gp_Vec theNormal3 = theNormal;

			if (theNormal.Magnitude() > Precision::Confusion())
			{
				theNormal.Normalize();
				theNormal1.Normalize();
				theNormal2.Normalize();
				theNormal3.Normalize();
			}

			theProp.SetParameters(theUV1.X(), theUV1.Y());
			if (theProp.IsNormalDefined())
			{
				theNormal1 = theProp.Normal();
			}

			theProp.SetParameters(theUV2.X(), theUV2.Y());
			if (theProp.IsNormalDefined())
			{
				theNormal2 = theProp.Normal();
			}

			theProp.SetParameters(theUV3.X(), theUV3.Y());
			if (theProp.IsNormalDefined())
			{
				theNormal3 = theProp.Normal();
			}

			if (theFace.Orientation() == TopAbs_REVERSED)
			{
				theNormal.Reverse();
				theNormal1.Reverse();
				theNormal2.Reverse();
				theNormal3.Reverse();
			}

			theVertices->push_back(osg::Vec3(theVertex1.X(), theVertex1.Y(), theVertex1.Z()));
			theVertices->push_back(osg::Vec3(theVertex2.X(), theVertex2.Y(), theVertex2.Z()));
			theVertices->push_back(osg::Vec3(theVertex3.X(), theVertex3.Y(), theVertex3.Z()));

			if (bSetNormal)
			{
				theNormals->push_back(osg::Vec3(theNormal1.X(), theNormal1.Y(), theNormal1.Z()));
				theNormals->push_back(osg::Vec3(theNormal2.X(), theNormal2.Y(), theNormal2.Z()));
				theNormals->push_back(osg::Vec3(theNormal3.X(), theNormal3.Y(), theNormal3.Z()));
			}
			else
			{
				theNormals->push_back(osg::Vec3(theNormal.X(), theNormal.Y(), theNormal.Z()));
				theNormals->push_back(osg::Vec3(theNormal.X(), theNormal.Y(), theNormal.Z()));
				theNormals->push_back(osg::Vec3(theNormal.X(), theNormal.Y(), theNormal.Z()));
			}
		}
	}

	triGeom->setVertexArray(theVertices.get());
	triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, theVertices->size()));

	triGeom->setNormalArray(theNormals);
	triGeom->setNormalBinding(deprecated_osg::Geometry::BIND_PER_VERTEX);

	osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array();
	colArr->push_back(color);
	triGeom->setColorArray(colArr, osg::Array::BIND_OVERALL);

	geode->addDrawable(triGeom);
}
bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh&         aMesh,
        const TopoDS_Shape& aShape)
{
    netgen::multithread.terminate = 0;
    //netgen::multithread.task = "Surface meshing";

    SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
    SMESH_MesherHelper helper(aMesh);
    helper.SetElementsOnShape( true );

    NETGENPlugin_NetgenLibWrapper ngLib;
    ngLib._isComputeOk = false;

    netgen::Mesh   ngMeshNoLocSize;
#if NETGEN_VERSION < 6
    netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh,  & ngMeshNoLocSize };
#else
    netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh.get(),  & ngMeshNoLocSize };
#endif
    netgen::OCCGeometry occgeoComm;

    // min / max sizes are set as follows:
    // if ( _hypParameters )
    //    min and max are defined by the user
    // else if ( _hypLengthFromEdges )
    //    min = aMesher.GetDefaultMinSize()
    //    max = average segment len of a FACE
    // else if ( _hypMaxElementArea )
    //    min = aMesher.GetDefaultMinSize()
    //    max = f( _hypMaxElementArea )
    // else
    //    min = aMesher.GetDefaultMinSize()
    //    max = max segment len of a FACE

    NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false);
    aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam
    const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true;
    if ( _hypMaxElementArea )
    {
        netgen::mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) );
    }
    if ( _hypQuadranglePreference )
        netgen::mparam.quad = true;

    // local size is common for all FACEs in aShape?
    const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && netgen::mparam.uselocalh );
    const bool isDefaultHyp = ( !_hypLengthFromEdges && !_hypMaxElementArea && !_hypParameters );

    if ( isCommonLocalSize ) // compute common local size in ngMeshes[0]
    {
        //list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm
        aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM );

        // local size set at MESHCONST_ANALYSE step depends on
        // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user
        if ( !_hypParameters || netgen::mparam.minh < DBL_MIN )
        {
            if ( !_hypParameters )
                netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.;
            netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh );
        }
        // set local size depending on curvature and NOT closeness of EDGEs
        netgen::occparam.resthcloseedgeenable = false;
        //netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading;
        occgeoComm.face_maxh = netgen::mparam.maxh;
        netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] );
        occgeoComm.emap.Clear();
        occgeoComm.vmap.Clear();

        // set local size according to size of existing segments
        const double factor = netgen::occparam.resthcloseedgefac;
        TopTools_IndexedMapOfShape edgeMap;
        TopExp::MapShapes( aMesh.GetShapeToMesh(), TopAbs_EDGE, edgeMap );
        for ( int iE = 1; iE <= edgeMap.Extent(); ++iE )
        {
            const TopoDS_Shape& edge = edgeMap( iE );
            if ( SMESH_Algo::isDegenerated( TopoDS::Edge( edge ))/* ||
           helper.IsSubShape( edge, aShape )*/)
                continue;
            SMESHDS_SubMesh* smDS = meshDS->MeshElements( edge );
            if ( !smDS ) continue;
            SMDS_ElemIteratorPtr segIt = smDS->GetElements();
            while ( segIt->more() )
            {
                const SMDS_MeshElement* seg = segIt->next();
                SMESH_TNodeXYZ n1 = seg->GetNode(0);
                SMESH_TNodeXYZ n2 = seg->GetNode(1);
                gp_XYZ p = 0.5 * ( n1 + n2 );
                netgen::Point3d pi(p.X(), p.Y(), p.Z());
                ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() );
            }
        }
    }
    netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization

    // ==================
    // Loop on all FACEs
    // ==================

    vector< const SMDS_MeshNode* > nodeVec;

    TopExp_Explorer fExp( aShape, TopAbs_FACE );
    for ( int iF = 0; fExp.More(); fExp.Next(), ++iF )
    {
        TopoDS_Face F = TopoDS::Face( fExp.Current() /*.Oriented( TopAbs_FORWARD )*/);
        int    faceID = meshDS->ShapeToIndex( F );
        SMESH_ComputeErrorPtr& faceErr = aMesh.GetSubMesh( F )->GetComputeError();

        _quadraticMesh = helper.IsQuadraticSubMesh( F );
        const bool ignoreMediumNodes = _quadraticMesh;

        // build viscous layers if required
        if ( F.Orientation() != TopAbs_FORWARD &&
                F.Orientation() != TopAbs_REVERSED )
            F.Orientation( TopAbs_FORWARD ); // avoid pb with TopAbs_INTERNAL
        SMESH_ProxyMesh::Ptr proxyMesh = StdMeshers_ViscousLayers2D::Compute( aMesh, F );
        if ( !proxyMesh )
            continue;

        // ------------------------
        // get all EDGEs of a FACE
        // ------------------------
        TSideVector wires =
            StdMeshers_FaceSide::GetFaceWires( F, aMesh, ignoreMediumNodes, faceErr, proxyMesh );
        if ( faceErr && !faceErr->IsOK() )
            continue;
        int nbWires = wires.size();
        if ( nbWires == 0 )
        {
            faceErr.reset
            ( new SMESH_ComputeError
              ( COMPERR_ALGO_FAILED, "Problem in StdMeshers_FaceSide::GetFaceWires()" ));
            continue;
        }
        if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments
        {
            faceErr.reset
            ( new SMESH_ComputeError
              ( COMPERR_BAD_INPUT_MESH, SMESH_Comment("Too few segments: ")<<wires[0]->NbSegments()) );
            continue;
        }

        // ----------------------
        // compute maxh of a FACE
        // ----------------------

        if ( !_hypParameters )
        {
            double edgeLength = 0;
            if (_hypLengthFromEdges )
            {
                // compute edgeLength as an average segment length
                int nbSegments = 0;
                for ( int iW = 0; iW < nbWires; ++iW )
                {
                    edgeLength += wires[ iW ]->Length();
                    nbSegments += wires[ iW ]->NbSegments();
                }
                if ( nbSegments )
                    edgeLength /= nbSegments;
                netgen::mparam.maxh = edgeLength;
            }
            else if ( isDefaultHyp )
            {
                // set edgeLength by a longest segment
                double maxSeg2 = 0;
                for ( int iW = 0; iW < nbWires; ++iW )
                {
                    const UVPtStructVec& points = wires[ iW ]->GetUVPtStruct();
                    if ( points.empty() )
                        return error( COMPERR_BAD_INPUT_MESH );
                    gp_Pnt pPrev = SMESH_TNodeXYZ( points[0].node );
                    for ( size_t i = 1; i < points.size(); ++i )
                    {
                        gp_Pnt p = SMESH_TNodeXYZ( points[i].node );
                        maxSeg2 = Max( maxSeg2, p.SquareDistance( pPrev ));
                        pPrev = p;
                    }
                }
                edgeLength = sqrt( maxSeg2 ) * 1.05;
                netgen::mparam.maxh = edgeLength;
            }
            if ( netgen::mparam.maxh < DBL_MIN )
                netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam();

            if ( !isCommonLocalSize )
            {
                netgen::mparam.minh = aMesher.GetDefaultMinSize( F, netgen::mparam.maxh );
            }
        }

        // prepare occgeom
        netgen::OCCGeometry occgeom;
        occgeom.shape = F;
        occgeom.fmap.Add( F );
        occgeom.CalcBoundingBox();
        occgeom.facemeshstatus.SetSize(1);
        occgeom.facemeshstatus = 0;
        occgeom.face_maxh_modified.SetSize(1);
        occgeom.face_maxh_modified = 0;
        occgeom.face_maxh.SetSize(1);
        occgeom.face_maxh = netgen::mparam.maxh;

        // -------------------------
        // Fill netgen mesh
        // -------------------------

        // MESHCONST_ANALYSE step may lead to a failure, so we make an attempt
        // w/o MESHCONST_ANALYSE at the second loop
        int err = 0;
        enum { LOC_SIZE, NO_LOC_SIZE };
        int iLoop = isCommonLocalSize ? 0 : 1;
        for ( ; iLoop < 2; iLoop++ )
        {
            //bool isMESHCONST_ANALYSE = false;
            InitComputeError();

            netgen::Mesh * ngMesh = ngMeshes[ iLoop ];
            ngMesh->DeleteMesh();

            if ( iLoop == NO_LOC_SIZE )
            {
                ngMesh->SetGlobalH ( mparam.maxh );
                ngMesh->SetMinimalH( mparam.minh );
                Box<3> bb = occgeom.GetBoundingBox();
                bb.Increase (bb.Diam()/10);
                ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading);
            }

            nodeVec.clear();
            faceErr = aMesher.AddSegmentsToMesh( *ngMesh, occgeom, wires, helper, nodeVec,
                                                 /*overrideMinH=*/!_hypParameters);
            if ( faceErr && !faceErr->IsOK() )
                break;

            //if ( !isCommonLocalSize )
            //limitSize( ngMesh, mparam.maxh * 0.8);

            // -------------------------
            // Generate surface mesh
            // -------------------------

            const int startWith = MESHCONST_MESHSURFACE;
            const int endWith   = toOptimize ? MESHCONST_OPTSURFACE : MESHCONST_MESHSURFACE;

            SMESH_Comment str;
            try {
                OCC_CATCH_SIGNALS;

#if NETGEN_VERSION >=6
                std::shared_ptr<netgen::Mesh> mesh_ptr(ngMesh,  [](netgen::Mesh*) {});
                err = netgen::OCCGenerateMesh(occgeom, mesh_ptr, netgen::mparam, startWith, endWith);
#elif NETGEN_VERSION > 4
                err = netgen::OCCGenerateMesh(occgeom, ngMesh, netgen::mparam, startWith, endWith);
#else
                char *optstr = 0;
                err = netgen::OCCGenerateMesh(occgeom, ngMesh, startWith, endWith, optstr);
#endif
                if ( netgen::multithread.terminate )
                    return false;
                if ( err )
                    str << "Error in netgen::OCCGenerateMesh() at " << netgen::multithread.task;
            }
            catch (Standard_Failure& ex)
            {
                err = 1;
                str << "Exception in  netgen::OCCGenerateMesh()"
                    << " at " << netgen::multithread.task
                    << ": " << ex.DynamicType()->Name();
                if ( ex.GetMessageString() && strlen( ex.GetMessageString() ))
                    str << ": " << ex.GetMessageString();
            }
            catch (...) {
                err = 1;
                str << "Exception in  netgen::OCCGenerateMesh()"
                    << " at " << netgen::multithread.task;
            }
            if ( err )
            {
                if ( aMesher.FixFaceMesh( occgeom, *ngMesh, 1 ))
                    break;
                if ( iLoop == LOC_SIZE )
                {
                    netgen::mparam.minh = netgen::mparam.maxh;
                    netgen::mparam.maxh = 0;
                    for ( int iW = 0; iW < wires.size(); ++iW )
                    {
                        StdMeshers_FaceSidePtr wire = wires[ iW ];
                        const vector<UVPtStruct>& uvPtVec = wire->GetUVPtStruct();
                        for ( size_t iP = 1; iP < uvPtVec.size(); ++iP )
                        {
                            SMESH_TNodeXYZ   p( uvPtVec[ iP ].node );
                            netgen::Point3d np( p.X(),p.Y(),p.Z());
                            double segLen = p.Distance( uvPtVec[ iP-1 ].node );
                            double   size = ngMesh->GetH( np );
                            netgen::mparam.minh = Min( netgen::mparam.minh, size );
                            netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen );
                        }
                    }
                    //cerr << "min " << netgen::mparam.minh << " max " << netgen::mparam.maxh << endl;
                    netgen::mparam.minh *= 0.9;
                    netgen::mparam.maxh *= 1.1;
                    continue;
                }
                else
                {
                    faceErr.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, str ));
                }
            }


            // ----------------------------------------------------
            // Fill the SMESHDS with the generated nodes and faces
            // ----------------------------------------------------

            int nbNodes = ngMesh->GetNP();
            int nbFaces = ngMesh->GetNSE();

            int nbInputNodes = nodeVec.size()-1;
            nodeVec.resize( nbNodes+1, 0 );

            // add nodes
            for ( int ngID = nbInputNodes + 1; ngID <= nbNodes; ++ngID )
            {
                const MeshPoint& ngPoint = ngMesh->Point( ngID );
                SMDS_MeshNode * node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2));
                nodeVec[ ngID ] = node;
            }

            // create faces
            int i,j;
            vector<const SMDS_MeshNode*> nodes;
            for ( i = 1; i <= nbFaces ; ++i )
            {
                const Element2d& elem = ngMesh->SurfaceElement(i);
                nodes.resize( elem.GetNP() );
                for (j=1; j <= elem.GetNP(); ++j)
                {
                    int pind = elem.PNum(j);
                    if ( pind < 1 )
                        break;
                    nodes[ j-1 ] = nodeVec[ pind ];
                    if ( nodes[ j-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE )
                    {
                        const PointGeomInfo& pgi = elem.GeomInfoPi(j);
                        meshDS->SetNodeOnFace( nodes[ j-1 ], faceID, pgi.u, pgi.v);
                    }
                }
                if ( j > elem.GetNP() )
                {
                    SMDS_MeshFace* face = 0;
                    if ( elem.GetType() == TRIG )
                        face = helper.AddFace(nodes[0],nodes[1],nodes[2]);
                    else
                        face = helper.AddFace(nodes[0],nodes[1],nodes[2],nodes[3]);
                }
            }

            break;
        } // two attempts
    } // loop on FACEs

    return true;
}
Esempio n. 11
0
//=======================================================================
//function :IsSplitToReverse
//purpose  : 
//=======================================================================
  Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Face& theFSp,
                                                     const TopoDS_Face& theFSr,
                                                     IntTools_Context& theContext)
{
  Standard_Boolean bRet, bFound, bInFace;
  Standard_Real aT1, aT2, aT, aU, aV, aScPr;
  gp_Pnt aPFSp, aPFSr;
  gp_Dir aDNFSp;
  gp_Vec aD1U, aD1V;
  Handle(Geom_Surface) aSr, aSp;
  TopAbs_Orientation aOrSr, aOrSp;
  TopExp_Explorer anExp;
  TopoDS_Edge aESp;
  //
  bRet=Standard_False;
  //
  aSr=BRep_Tool::Surface(theFSr);
  aSp=BRep_Tool::Surface(theFSp);
  if (aSr==aSp) {
    aOrSr=theFSr.Orientation();
    aOrSp=theFSp.Orientation();
    bRet=(aOrSr!=aOrSp);
    return bRet;
  }
  //
  bFound=Standard_False;
  anExp.Init(theFSp, TopAbs_EDGE);
  for (; anExp.More(); anExp.Next()) {
    aESp=TopoDS::Edge(anExp.Current());
    if (!BRep_Tool::Degenerated(aESp)) {
      if (!BRep_Tool::IsClosed(aESp, theFSp)) {
        bFound=!bFound;
        break;
      }
    }
  }
  if (!bFound) {
    return bRet;
  }
  //
  BRep_Tool::Range(aESp, aT1, aT2);
  aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
  BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp);
  //
  // Parts of theContext.ComputeVS(..) 
  GeomAPI_ProjectPointOnSurf& aProjector=theContext.ProjPS(theFSr);
  aProjector.Perform(aPFSp);
  if (!aProjector.IsDone()) {
    return bRet;
  }
  //
  aProjector.LowerDistanceParameters(aU, aV);
  gp_Pnt2d aP2D(aU, aV);
  bInFace=theContext.IsPointInFace (theFSr, aP2D);
  if (!bInFace) {
    return bRet;
  }
  //
  aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
  gp_Dir aDD1U(aD1U); 
  gp_Dir aDD1V(aD1V);
  gp_Dir aDNFSr=aDD1U^aDD1V; 
  if (theFSr.Orientation()==TopAbs_REVERSED){
    aDNFSr.Reverse();
  }
  //
  aScPr=aDNFSp*aDNFSr;
  bRet=(aScPr<0.);
  //
  return bRet;
}
Esempio n. 12
0
//=======================================================================
//function : GetApproxNormalToFaceOnEdge
//purpose  : 
//=======================================================================
void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aEx, 
                                  const TopoDS_Face& aFx, 
                                  Standard_Real aT, 
                                  gp_Pnt& aPF, 
                                  gp_Dir& aDNF,
                                  IntTools_Context& aCtx)
{
  Standard_Boolean bReverse;
  Standard_Real aT1, aT2, dT, aU, aV;
  gp_Dir aDTT, aDNFT, aDBT;
  gp_Pnt aPFT, aPFx;
  Handle(Geom_Curve) aC3D;
  Handle(Geom_Surface) aS;
  GeomAdaptor_Surface aGAS;
  GeomAbs_SurfaceType aTS;
  TopoDS_Face aF;
  TopoDS_Edge aE;
  //
  bReverse=Standard_False;
  aF=aFx;
  aE=aEx;
  if (aF.Orientation()==TopAbs_REVERSED){
    bReverse=!bReverse;
    aE.Reverse();
    //
    aF.Orientation(TopAbs_FORWARD);
  }
  //
  // Point at aT
  aC3D =BRep_Tool::Curve(aE, aT1, aT2);
  aC3D->D0(aT, aPFT);
  //
  // Normal at aT
  BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNFT);
  
  // Tangent at aT
  BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDTT);
  //
  // Binormal at aT
  aDBT=aDNFT^aDTT;
  //
  dT=BOPTools_Tools3D::MinStepIn2d();//~1.e-5;
  dT=10.*dT;
  //----------------------------------------------
  {
    aS=BRep_Tool::Surface(aF);
    aGAS.Load(aS);
    aTS=aGAS.GetType();
    if (aTS==GeomAbs_BSplineSurface ||
        aTS==GeomAbs_BezierSurface ||
        aTS==GeomAbs_Plane) {
      Standard_Real aTolEx, aTolFx, aTol, dUR, dVR, dR;
      //
      aTolEx=BRep_Tool::Tolerance(aEx);
      aTolFx=BRep_Tool::Tolerance(aFx);
      aTol=2.*aTolEx+aTolFx;
      dUR=aGAS.UResolution(aTol);
      dVR=aGAS.VResolution(aTol);
      dR=(dUR>dVR)? dUR : dVR;
      if (dR>dT) {
        dT=dR;
      }
    }
    //modified by NIZNHY-PKV Thu Dec 02 10:39:09 2010f
    else if (GeomAbs_Torus ||
             aTS==GeomAbs_Cylinder){
      Standard_Real aTolEx, aTolFx, aTol;
      //
      aTolEx=BRep_Tool::Tolerance(aEx);
      aTolFx=BRep_Tool::Tolerance(aFx);
      aTol=2.*aTolEx+aTolFx;
      if (aTol>dT) {
        dT=aTol;
      }
    }
    //modified by NIZNHY-PKV Thu Dec 02 10:39:13 2010t
  }
  //----------------------------------------------
  //
  aPFx.SetXYZ(aPFT.XYZ()+dT*aDBT.XYZ());
  //
  aPF=aPFx;
  aDNF=aDNFT;
  if (bReverse) {
    aDNF.Reverse();
  }
  //
  GeomAPI_ProjectPointOnSurf& aProjector=aCtx.ProjPS(aF);
  //
  aProjector.Perform(aPFx);
  if(aProjector.IsDone()) {
    aProjector.LowerDistanceParameters (aU, aV);
    aS->D0(aU, aV, aPF);
    BOPTools_Tools3D::GetNormalToSurface (aS, aU, aV, aDNF);
    if (bReverse){
      aDNF.Reverse();
    }
  }
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IMeasure aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == CDG_MEASURE)
  {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Shape for centre of mass calculation is null");
    }

    gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aShapeBase);
    gp_Pnt aCenterMass = aPos.Location();
    aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
  }
  else if (aType == VERTEX_BY_INDEX)
  {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Shape for centre of mass calculation is null");
    }

    int index = aCI.GetIndex();
    gp_Pnt aVertex;

    if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
      if ( index != 1 )
        Standard_NullObject::Raise("Vertex index is out of range");
      else
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase));
    } else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
      TopoDS_Vertex aV1, aV2;
      TopoDS_Edge anEdgeE = TopoDS::Edge(aShapeBase);
      
      TopExp::Vertices(anEdgeE, aV1, aV2);
      gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
      gp_Pnt aP2 = BRep_Tool::Pnt(aV2);

      if (index < 0 || index > 1)
        Standard_NullObject::Raise("Vertex index is out of range");

      if ( ( anEdgeE.Orientation() == TopAbs_FORWARD && index == 0 ) ||
           ( anEdgeE.Orientation() == TopAbs_REVERSED && index == 1 ) )
        aVertex = aP1;
      else
      aVertex = aP2;
    } else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
      TopTools_IndexedMapOfShape anEdgeShapes;
      TopTools_IndexedMapOfShape aVertexShapes;
      TopoDS_Vertex aV1, aV2;
      TopoDS_Wire aWire = TopoDS::Wire(aShapeBase);
      TopExp_Explorer exp (aWire, TopAbs_EDGE);
      for (; exp.More(); exp.Next()) {
        anEdgeShapes.Add(exp.Current());
        TopoDS_Edge E = TopoDS::Edge(exp.Current());
        TopExp::Vertices(E, aV1, aV2);
        if ( aVertexShapes.Extent() == 0)
          aVertexShapes.Add(aV1);
        if ( !aV1.IsSame( aVertexShapes(aVertexShapes.Extent()) ) )
          aVertexShapes.Add(aV1);
        if ( !aV2.IsSame( aVertexShapes(aVertexShapes.Extent()) ) )
          aVertexShapes.Add(aV2);
      }

      if (index < 0 || index > aVertexShapes.Extent())
        Standard_NullObject::Raise("Vertex index is out of range");

      if (aWire.Orientation() == TopAbs_FORWARD)
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(index+1)));
      else
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(aVertexShapes.Extent() - index)));
    } else {
      Standard_NullObject::Raise("Shape for vertex calculation is not an edge or wire");
    }

    aShape = BRepBuilderAPI_MakeVertex(aVertex).Shape();
  }
  else if (aType == VECTOR_FACE_NORMALE)
  {
    // Face
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Face for normale calculation is null");
    }
    if (aShapeBase.ShapeType() != TopAbs_FACE) {
      Standard_NullObject::Raise("Shape for normale calculation is not a face");
    }
    TopoDS_Face aFace = TopoDS::Face(aShapeBase);

    // Point
    gp_Pnt p1 (0,0,0);

    Handle(GEOM_Function) aPntFunc = aCI.GetPoint();
    if (!aPntFunc.IsNull())
    {
      TopoDS_Shape anOptPnt = aPntFunc->GetValue();
      if (anOptPnt.IsNull())
        Standard_NullObject::Raise("Invalid shape given for point argument");
      p1 = BRep_Tool::Pnt(TopoDS::Vertex(anOptPnt));
    }
    else
    {
      gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aFace);
      p1 = aPos.Location();
    }

    // Point parameters on surface
    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
    Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf);
    gp_Pnt2d pUV = aSurfAna->ValueOfUV(p1, Precision::Confusion());

    // Normal direction
    gp_Vec Vec1,Vec2;
    BRepAdaptor_Surface SF (aFace);
    SF.D1(pUV.X(), pUV.Y(), p1, Vec1, Vec2);
    if (Vec1.Magnitude() < Precision::Confusion()) {
      gp_Vec tmpV;
      gp_Pnt tmpP;
      SF.D1(pUV.X(), pUV.Y()-0.1, tmpP, Vec1, tmpV);
    }
    else if (Vec2.Magnitude() < Precision::Confusion()) {
      gp_Vec tmpV;
      gp_Pnt tmpP;
      SF.D1(pUV.X()-0.1, pUV.Y(), tmpP, tmpV, Vec2);
    }

    gp_Vec V = Vec1.Crossed(Vec2);
    Standard_Real mod = V.Magnitude();
    if (mod < Precision::Confusion())
      Standard_NullObject::Raise("Normal vector of a face has null magnitude");

    // Set length of normal vector to average radius of curvature
    Standard_Real radius = 0.0;
    GeomLProp_SLProps aProperties (aSurf, pUV.X(), pUV.Y(), 2, Precision::Confusion());
    if (aProperties.IsCurvatureDefined()) {
      Standard_Real radius1 = Abs(aProperties.MinCurvature());
      Standard_Real radius2 = Abs(aProperties.MaxCurvature());
      if (Abs(radius1) > Precision::Confusion()) {
        radius = 1.0 / radius1;
        if (Abs(radius2) > Precision::Confusion()) {
          radius = (radius + 1.0 / radius2) / 2.0;
        }
      }
      else {
        if (Abs(radius2) > Precision::Confusion()) {
          radius = 1.0 / radius2;
        }
      }
    }

    // Set length of normal vector to average dimension of the face
    // (only if average radius of curvature is not appropriate)
    if (radius < Precision::Confusion()) {
        Bnd_Box B;
        Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
        BRepBndLib::Add(aFace, B);
        B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
        radius = ((Xmax - Xmin) + (Ymax - Ymin) + (Zmax - Zmin)) / 3.0;
    }

    if (radius < Precision::Confusion())
      radius = 1.0;

    V *= radius / mod;

    // consider the face orientation
    if (aFace.Orientation() == TopAbs_REVERSED ||
        aFace.Orientation() == TopAbs_INTERNAL) {
      V = - V;
    }

    // Edge
    gp_Pnt p2 = p1.Translated(V);
    BRepBuilderAPI_MakeEdge aBuilder (p1, p2);
    if (!aBuilder.IsDone())
      Standard_NullObject::Raise("Vector construction failed");
    aShape = aBuilder.Shape();
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;
}
Esempio n. 14
0
//=======================================================================
//function : SelectEdge
//purpose  : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>.
//           <NE> Is erased  of the list. If <CE> is too in the list <LE> 
//			 with the same orientation, it's erased of the list 
//=======================================================================
static Standard_Boolean  SelectEdge(const TopoDS_Face&    F,
				    const TopoDS_Edge&    CE,
				    const TopoDS_Vertex&  CV,
				    TopoDS_Edge&          NE,
				    TopTools_ListOfShape& LE)
{
  TopTools_ListIteratorOfListOfShape itl;
  NE.Nullify();
  for ( itl.Initialize(LE); itl.More(); itl.Next()) {
    if (itl.Value().IsEqual(CE)) {
      LE.Remove(itl);
      break;
    }
  }

  if (LE.Extent() > 1) {
    //--------------------------------------------------------------
    // Several possible edges.   
    // - Test the edges differents of CE 
    //--------------------------------------------------------------
    Standard_Real   cf, cl, f, l;
    TopoDS_Face FForward = F;
    Handle(Geom2d_Curve) Cc, C;
    FForward.Orientation(TopAbs_FORWARD);
			
    Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl);
    Standard_Real dist,distmin  = 100*BRep_Tool::Tolerance(CV);
    Standard_Real uc,u;
    if (CE.Orientation () == TopAbs_FORWARD) uc = cl;
    else                                     uc = cf;

    gp_Pnt2d P2,PV = Cc->Value(uc); 

    Standard_Real delta = FindDelta(LE,FForward);

    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (!E.IsSame(CE)) {
	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
	if (E.Orientation () == TopAbs_FORWARD) u = f;
	else                                    u = l;
	P2 = C->Value(u);
	dist = PV.Distance(P2);
	if (dist <= distmin){
	  distmin = dist;
	}
				
      }
    }

    Standard_Real anglemax = - PI;
    TopoDS_Edge   SelectedEdge;	
    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (!E.IsSame(CE)) {
	C = BRep_Tool::CurveOnSurface(E,FForward,f,l);
	if (E.Orientation () == TopAbs_FORWARD) u = f;
	else                                    u = l;
	P2 = C->Value(u);
	dist = PV.Distance(P2);
	if (dist <= distmin + (1./3)*delta){ 
	  gp_Pnt2d PC, P;
	  gp_Vec2d CTg1, CTg2, Tg1, Tg2;
	  Cc->D2(uc, PC, CTg1, CTg2);
	  C->D2(u, P, Tg1, Tg2);

	  Standard_Real angle;

	  if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) {
	    angle = CTg1.Angle(Tg1.Reversed());
	  }
	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) {
	    angle = (CTg1.Reversed()).Angle(Tg1);
	  }
	  else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) {
	    angle = CTg1.Angle(Tg1);
	  }
	  else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) {
	    angle = (CTg1.Reversed()).Angle(Tg1.Reversed());
	  }
	  if (angle >= anglemax) {
	    anglemax = angle ;
	    SelectedEdge = E;	
	  }
	}
      }
    }
    for ( itl.Initialize(LE); itl.More(); itl.Next()) {
      const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
      if (E.IsEqual(SelectedEdge)) {
	NE = TopoDS::Edge(E);
	LE.Remove(itl);
	break;
      }
    }					
  }
  else if (LE.Extent() == 1) {
    NE = TopoDS::Edge(LE.First());
    LE.RemoveFirst();
  }
  else {
    return Standard_False;
  }
  return Standard_True;
}
Esempio n. 15
0
void DrawFace(TopoDS_Face face,void(*callbackfunc)(const double* x, const double* n), bool just_one_average_normal)
{
	double x[9], n[9];

	StdPrs_ToolShadedShape SST;

	// Get triangulation
	TopLoc_Location L;
	Handle_Poly_Triangulation facing = BRep_Tool::Triangulation(face,L);
	gp_Trsf tr = L;

	if(facing.IsNull()){
#if 0
		BRepAdaptor_Surface surface(face, Standard_True);
		double u0 = surface.FirstUParameter();
		double u1 = surface.LastUParameter();
		double v0 = surface.FirstVParameter();
		double v1 = surface.LastVParameter();

		const int numi = 10;
		const int numj = 10;

		for(int i = 0; i<numi; i++)
		{
			for(int j = 0; j<numj; j++)
			{
				double uA = -1.2 + 2.5 *(double)i / numi;
				double uB = -1.2 + 2.5 *(double)(i+1) / numi;
				double vA = 10* (double)j / numj;
				double vB = 10*(double)(j+1) / numj;
				gp_Pnt p0, p1, p2, p3;
				gp_Dir n0 = GetFaceNormalAtUV(face, uA, vA, &p0);
				gp_Dir n1 = GetFaceNormalAtUV(face, uB, vA, &p1);
				gp_Dir n2 = GetFaceNormalAtUV(face, uB, vB, &p2);
				gp_Dir n3 = GetFaceNormalAtUV(face, uA, vB, &p3);

				x[0] = p0.X();
				x[1] = p0.Y();
				x[2] = p0.Z();
				x[3] = p1.X();
				x[4] = p1.Y();
				x[5] = p1.Z();
				x[6] = p2.X();
				x[7] = p2.Y();
				x[8] = p2.Z();

				n[0] = n0.X();
				n[1] = n0.Y();
				n[2] = n0.Z();
				n[3] = n1.X();
				n[4] = n1.Y();
				n[5] = n1.Z();
				n[6] = n2.X();
				n[7] = n2.Y();
				n[8] = n2.Z();

				(*callbackfunc)(x, n);

				x[0] = p0.X();
				x[1] = p0.Y();
				x[2] = p0.Z();
				x[3] = p2.X();
				x[4] = p2.Y();
				x[5] = p2.Z();
				x[6] = p3.X();
				x[7] = p3.Y();
				x[8] = p3.Z();

				n[0] = n0.X();
				n[1] = n0.Y();
				n[2] = n0.Z();
				n[3] = n2.X();
				n[4] = n2.Y();
				n[5] = n2.Z();
				n[6] = n3.X();
				n[7] = n3.Y();
				n[8] = n3.Z();

				(*callbackfunc)(x, n);
			}
		}
#endif
	}
	else
	{
		Poly_Connect pc(facing);	
		const TColgp_Array1OfPnt& Nodes = facing->Nodes();
		const Poly_Array1OfTriangle& triangles = facing->Triangles();
		TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());

		SST.Normal(face, pc, myNormal);

		Standard_Integer nnn = facing->NbTriangles();					// nnn : nombre de triangles
		Standard_Integer nt, n1, n2, n3 = 0;						// nt  : triangle courant
		// ni  : sommet i du triangle courant
		for (nt = 1; nt <= nnn; nt++)					
		{
			if (face.Orientation() == TopAbs_REVERSED)			// si la face est "reversed"
				triangles(nt).Get(n1,n3,n2);						// le triangle est n1,n3,n2
			else 
				triangles(nt).Get(n1,n2,n3);						// le triangle est n1,n2,n3

			if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
			{
				gp_Pnt v1 = Nodes(n1).Transformed(tr);
				gp_Pnt v2 = Nodes(n2).Transformed(tr);
				gp_Pnt v3 = Nodes(n3).Transformed(tr);

				x[0] = v1.X();
				x[1] = v1.Y();
				x[2] = v1.Z();
				x[3] = v2.X();
				x[4] = v2.Y();
				x[5] = v2.Z();
				x[6] = v3.X();
				x[7] = v3.Y();
				x[8] = v3.Z();

				if(just_one_average_normal)
				{
					gp_Vec V1(v1, v2);
					gp_Vec V2(v1, v3);
					extract((V1 ^ V2).Normalized(), n);
				}
				else
				{
					n[0] = myNormal(n1).X();
					n[1] = myNormal(n1).Y();
					n[2] = myNormal(n1).Z();
					n[3] = myNormal(n2).X();
					n[4] = myNormal(n2).Y();
					n[5] = myNormal(n2).Z();
					n[6] = myNormal(n3).X();
					n[7] = myNormal(n3).Y();
					n[8] = myNormal(n3).Z();
				}

				(*callbackfunc)(x, n);
			}
		}
	}
}