Skip to content

Commit

Permalink
fix TopoShape::getFacesFromSubelement
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Aug 4, 2016
1 parent 5fb7fae commit 461c0b1
Showing 1 changed file with 88 additions and 117 deletions.
205 changes: 88 additions & 117 deletions src/Mod/Part/App/TopoShape.cpp
Expand Up @@ -257,123 +257,6 @@ Data::Segment* TopoShape::getSubElement(const char* Type, unsigned long n) const
return new ShapeSegment(getSubShape(temp.c_str()));
}

void TopoShape::getLinesFromSubelement(const Data::Segment* element,
std::vector<Base::Vector3d> &Points,
std::vector<Line> &lines) const
{
}

void TopoShape::getFacesFromSubelement(const Data::Segment* element,
std::vector<Base::Vector3d> &Points,
std::vector<Base::Vector3d> &PointNormals,
std::vector<Facet> &faces) const
{
if (element->getTypeId() == ShapeSegment::getClassTypeId()) {
const TopoDS_Shape& shape = static_cast<const ShapeSegment*>(element)->Shape;
if (shape.IsNull() || shape.ShapeType() != TopAbs_FACE)
return;

TopLoc_Location aLoc;
// doing the meshing and checking the result
Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(TopoDS::Face(shape),aLoc);
if (aPoly.IsNull())
return;

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

Standard_Integer i;
// geting size and create the array
int nbNodesInFace = aPoly->NbNodes();
int nbTriInFace = aPoly->NbTriangles();
Points.resize(nbNodesInFace);
PointNormals.resize(nbNodesInFace); // fills up already the array
faces.resize(nbTriInFace);

// check orientation
TopAbs_Orientation orient = shape.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
PointNormals[N1-1] += Base::Vector3d(Normal.X(),Normal.Y(),Normal.Z());
PointNormals[N2-1] += Base::Vector3d(Normal.X(),Normal.Y(),Normal.Z());
PointNormals[N3-1] += Base::Vector3d(Normal.X(),Normal.Y(),Normal.Z());

Points[N1-1].Set(V1.X(),V1.Y(),V1.Z());
Points[N2-1].Set(V2.X(),V2.Y(),V2.Z());
Points[N3-1].Set(V3.X(),V3.Y(),V3.Z());

int j = i - 1;
N1--;
N2--;
N3--;
faces[j].I1 = N1;
faces[j].I2 = N2;
faces[j].I3 = N3;
}

// normalize all vertex normals
for (i=0; i < nbNodesInFace; i++) {
gp_Dir clNormal;
try {
Handle_Geom_Surface Surface = BRep_Tool::Surface(TopoDS::Face(shape));

gp_Pnt vertex(Base::convertTo<gp_Pnt>(Points[i]));
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();
Base::Vector3d temp = Base::convertTo<Base::Vector3d>(clNormal);
if (temp * Points[i] < 0)
temp = -temp;
Points[i] = temp;
}
catch (...) {
}
Points[i].Normalize();
}
}
}

TopoDS_Shape TopoShape::getSubShape(const char* Type) const
{
if (!Type)
Expand Down Expand Up @@ -2706,3 +2589,91 @@ void TopoShape::getPoints(std::vector<Base::Vector3d> &Points,
if (!hasFaces)
Normals.clear();
}

void TopoShape::getLinesFromSubelement(const Data::Segment* element,
std::vector<Base::Vector3d> &Points,
std::vector<Line> &lines) const
{
}

void TopoShape::getFacesFromSubelement(const Data::Segment* element,
std::vector<Base::Vector3d> &Points,
std::vector<Base::Vector3d> &PointNormals,
std::vector<Facet> &faces) const
{
if (element->getTypeId() == ShapeSegment::getClassTypeId()) {
const TopoDS_Shape& shape = static_cast<const ShapeSegment*>(element)->Shape;
if (shape.IsNull() || shape.ShapeType() != TopAbs_FACE)
return;
std::set<MeshVertex> vertices;
Standard_Real x1, y1, z1;
Standard_Real x2, y2, z2;
Standard_Real x3, y3, z3;

Handle_StlMesh_Mesh aMesh = new StlMesh_Mesh();
#if OCC_VERSION_HEX >= 0x060801
StlTransfer::RetrieveMesh(shape, aMesh);
#else
throw Base::AttributeError("getFacesFromSubelement is available only in OCC 6.8.1 and up.");
#endif

StlMesh_MeshExplorer xp(aMesh);
for (Standard_Integer nbd=1;nbd<=aMesh->NbDomains();nbd++) {
for (xp.InitTriangle (nbd); xp.MoreTriangle (); xp.NextTriangle ()) {
xp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3);
Data::ComplexGeoData::Facet face;
std::set<MeshVertex>::iterator it;

// 1st vertex
MeshVertex v1(x1,y1,z1);
it = vertices.find(v1);
if (it == vertices.end()) {
v1.i = vertices.size();
face.I1 = v1.i;
vertices.insert(v1);
}
else {
face.I1 = it->i;
}

// 2nd vertex
MeshVertex v2(x2,y2,z2);
it = vertices.find(v2);
if (it == vertices.end()) {
v2.i = vertices.size();
face.I2 = v2.i;
vertices.insert(v2);
}
else {
face.I2 = it->i;
}

// 3rd vertex
MeshVertex v3(x3,y3,z3);
it = vertices.find(v3);
if (it == vertices.end()) {
v3.i = vertices.size();
face.I3 = v3.i;
vertices.insert(v3);
}
else {
face.I3 = it->i;
}

// make sure that we don't insert invalid facets
if (face.I1 != face.I2 &&
face.I2 != face.I3 &&
face.I3 != face.I1)
faces.push_back(face);
}
}

(void)PointNormals; // leave this empty
std::vector<gp_Pnt> points;
points.resize(vertices.size());
for (std::set<MeshVertex>::iterator it = vertices.begin(); it != vertices.end(); ++it)
points[it->i] = it->toPoint();
for (std::vector<gp_Pnt>::iterator it = points.begin(); it != points.end(); ++it)
Points.push_back(Base::Vector3d(it->X(),it->Y(),it->Z()));
}
}

0 comments on commit 461c0b1

Please sign in to comment.