Files
create/src/Mod/Cam/App/SpringbackCorrection.cpp

3098 lines
94 KiB
C++

/***************************************************************************
* Copyright (c) 2007 *
* Joachim Zettler <Joachim.Zettler@gmx.de> *
* Human Rezai <Human@web.de> *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#include "SpringbackCorrection.h"
#include "best_fit.h"
#include <Mod/Mesh/App/Core/Builder.h>
#include <Mod/Mesh/App/WildMagic4/Wm4MeshCurvature.h>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <Base/Builder3D.h>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <BRepTools.hxx>
#include <BRep_Builder.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Triangulation.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <TopExp_Explorer.hxx>
#include <TopExp.hxx>
#include <TopoDS_Vertex.hxx>
#include <BRep_Tool.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <TopoDS.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <Geom_Surface.hxx>
///*********BINDINGS********/
#include <boost/numeric/bindings/traits/ublas_matrix.hpp>
#include <boost/numeric/bindings/atlas/clapack.hpp>
using namespace boost::numeric::bindings;
using namespace boost::numeric;
SpringbackCorrection::SpringbackCorrection()
{
}
SpringbackCorrection::SpringbackCorrection(const TopoDS_Shape& aShape, const MeshCore::MeshKernel& aMesh)
:m_Shape(aShape),m_Mesh(aMesh)
{
m_EdgeStruct.clear();
EdgeMap.clear();
MeshMap.clear();
//Remove any existing Triangulation on the Shape
BRepTools::Clean(m_Shape);
best_fit::Tesselate_Shape(m_Shape,m_CadMesh,(float) 0.1); // Basistriangulierung des ganzen Shapes
MeshCore::MeshTopoAlgorithm algo(m_CadMesh);
algo.HarmonizeNormals();
// flip all normals so that they are oriented in positive z-direction
MeshCore::MeshGeomFacet facet = m_CadMesh.GetFacet(0);
if (facet.GetNormal().z < 0.0)
algo.FlipNormals();
int n = m_CadMesh.CountFacets();
Base::Vector3f normal;
MeshCore::MeshPointArray points = m_CadMesh.GetPoints();
MeshCore::MeshFacetArray facets = m_CadMesh.GetFacets();
for (int i=0; i<n; ++i)
{
MeshCore::MeshGeomFacet face = m_CadMesh.GetFacet(i);
normal = face.GetNormal();
if (normal.z < 0.0)
{
facets[i].FlipNormal();
}
}
m_CadMesh.Assign(points, facets);
}
SpringbackCorrection::~SpringbackCorrection()
{
}
bool SpringbackCorrection::Load(const MeshCore::MeshKernel& aMesh)
{
m_MeshVec.push_back(aMesh);
//m_CadMesh = MeshRef;
return true;
}
bool SpringbackCorrection::Load(const TopoDS_Shape& aShape)
{
m_Shape = aShape;
return true;
}
bool SpringbackCorrection::Load(const TopoDS_Shape& aShape, const MeshCore::MeshKernel& aMesh)
{
m_Shape = aShape;
m_Mesh = aMesh;
m_EdgeStruct.clear();
EdgeMap.clear();
MeshMap.clear();
//Remove any existing Triangulation on the Shape
BRepTools::Clean(m_Shape);
best_fit::Tesselate_Shape(m_Shape,m_CadMesh,(float) 0.1); // Basistriangulierung des ganzen Shapes
MeshCore::MeshTopoAlgorithm algo(m_CadMesh);
algo.HarmonizeNormals();
MeshCore::MeshGeomFacet facet = m_CadMesh.GetFacet(0);
if (facet.GetNormal().z < 0.0)
algo.FlipNormals();
int n = m_CadMesh.CountFacets();
Base::Vector3f normal;
//MeshCore::MeshPointArray points = m_CadMesh.GetPoints();
//MeshCore::MeshFacetArray facets = m_CadMesh.GetFacets();
//for (int i=0; i<n; ++i)
//{
// MeshCore::MeshGeomFacet face = m_CadMesh.GetFacet(i);
// normal = face.GetNormal();
// if (normal.z < 0.0)
// {
// facets[i].FlipNormal();
// }
//}
//m_CadMesh.Assign(points, facets);
return true;
}
bool SpringbackCorrection::CalcCurv()
{
Base::Builder3D logo;
BRep_Builder VertexBuild;
BRepExtrema_DistShapeShape pnt2edge;
pnt2edge.SetDeflection(0.1);
TopExp_Explorer aExpFace;
TopExp_Explorer aExpEdge;
TopoDS_Vertex V;
MeshPnt aMeshStruct;
MeshCore::MeshPointIterator pntIt(m_CadMesh);
MeshCore::MeshKernel FaceMesh;
MeshCore::MeshPointArray MeshPnts, MeshPntsCop, MeshPntsCad;
MeshCore::MeshPointArray MeshPntsCopy;
MeshCore::MeshFacetArray MeshFacets, MeshFacets2;
MeshCore::MeshFacetIterator facetIt(m_CadMesh);
std::pair<Base::Vector3f, MeshPnt> inp;
std::vector<int> MeanVec;
std::vector<FacePnt> FacePntVector;
TopLoc_Location aloc;
Base::Vector3f mP;
gp_Pnt e_pnt, m_pnt;
double dist, distSum, revSum;;
int n;
std::map<TopoDS_Edge, std::vector<double>, Edge_Less>::iterator edge_it;
std::map<Base::Vector3f,MeshPnt,MeshPntLess >::iterator meshIt;
std::vector<MeshCore::MeshPoint>::iterator pIt;
m_CurvPos.resize(m_CadMesh.CountPoints());
m_CurvNeg.resize(m_CadMesh.CountPoints());
m_MeshStruct.resize(m_CadMesh.CountPoints());
MeanVec.resize(m_CadMesh.CountPoints(), 0);
// Fülle Map mit Punkten (Key) und deren, zur Basistriangulierung korrespondierenden, Indizes
MeshPnts = m_CadMesh.GetPoints();
MeshPntsCop = MeshPnts;
MeshFacets2 = m_CadMesh.GetFacets();
for (unsigned int i=0; i<MeshPnts.size(); ++i)
{
aMeshStruct.pnt = MeshPnts[i]; // stores point
aMeshStruct.index = i; // stores index
aMeshStruct.maxCurv = 1e+3;
aMeshStruct.minCurv = -1e+3;
inp.first = aMeshStruct.pnt;
inp.second = aMeshStruct;
MeshMap.insert(inp);
}
// explores all faces ------------ Hauptschleife
for (aExpFace.Init(m_Shape,TopAbs_FACE);aExpFace.More();aExpFace.Next())
{
TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
TransferFaceTriangulationtoFreeCAD(aFace, FaceMesh);
MeshPnts.clear();
MeshPnts = FaceMesh.GetPoints();
MeshPntsCopy = MeshPnts;
n = MeshPnts.size();
TopLoc_Location aLocation;
// berechne normalen -> m_MeshStruct
Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);
const TColgp_Array1OfPnt& aNodes = aTr->Nodes();
// create array of node points in absolute coordinate system
TColgp_Array1OfPnt aPoints(1, aNodes.Length());
for ( Standard_Integer i = 1; i <= aNodes.Length(); i++)
aPoints(i) = aNodes(i).Transformed(aLocation);
const TColgp_Array1OfPnt2d& aUVNodes = aTr->UVNodes();
BRepAdaptor_Surface aSurface(aFace);
Base::Vector3f Pnt1, Pnt2;
gp_Pnt2d par;
gp_Pnt P;
gp_Vec D1U, D1V;
for (int i=1; i<n+1; ++i)
{
par = aUVNodes.Value(i);
aSurface.D1(par.X(),par.Y(),P,D1U,D1V);
P = aPoints(i);
Pnt1.x = (float) P.X();
Pnt1.y = (float) P.Y();
Pnt1.z = (float) P.Z();
meshIt = MeshMap.find(Pnt1);
if (meshIt == MeshMap.end())
{
cout << "error";
return false;
}
D1U.Cross(D1V);
D1U.Normalize();
if (aFace.Orientation() == TopAbs_FORWARD) D1U.Scale(-1.0);
Pnt2.Set(float(Pnt1.x+D1U.X()),float(Pnt1.y+D1U.Y()),float(Pnt1.z+D1U.Z()));
logo.addSingleArrow(Pnt1, Pnt2);
m_MeshStruct[((*meshIt).second).index].normal.x = (float) D1U.X();
m_MeshStruct[((*meshIt).second).index].normal.y = (float) D1U.Y();
m_MeshStruct[((*meshIt).second).index].normal.z = (float) D1U.Z();
}
logo.saveToFile("c:/norm.iv");
// get Inner Mesh Points
int innerpoints = GetBoundary(FaceMesh, MeshPnts);
FacePntVector.resize(innerpoints); // stores inner-points and sourrounding edges-distances
// explores the edges of the face ----------------------
for (aExpEdge.Init(aFace,TopAbs_EDGE);aExpEdge.More();aExpEdge.Next())
{
TopoDS_Edge aEdge = TopoDS::Edge(aExpEdge.Current());
edge_it = EdgeMap.find(aEdge);
if (edge_it == EdgeMap.end())
{
cout << "error1";
return false;
}
pnt2edge.LoadS1(aEdge);
int counter = 0;
for (pIt = MeshPnts.begin(); pIt != MeshPnts.end(); ++pIt)
{
//check if there is no boundary
if (pIt->_ulProp == 0)
{
m_pnt.SetCoord(pIt->x, pIt->y, pIt->z);
VertexBuild.MakeVertex(V,m_pnt,0.001);
pnt2edge.LoadS2(V);
pnt2edge.Perform();
if (pnt2edge.IsDone() == false)
{
throw Base::Exception("couldn't perform distance calculation pnt2edge \n");
}
dist = pnt2edge.Value();
FacePntVector[counter].pnt = *pIt;
FacePntVector[counter].distances.push_back(dist);
FacePntVector[counter].MinEdgeOff.push_back((*edge_it).second[0]);
FacePntVector[counter].MaxEdgeOff.push_back((*edge_it).second[1]);
++counter;
}
}
// Knoten auf der EDGE die EdgeOffset-Werte zuweisen
// Edge -> Polygon -> Nodes
Handle(Poly_PolygonOnTriangulation) polyg;
Handle_Poly_Triangulation aTrLoc;
BRep_Tool::PolygonOnTriangulation(aEdge,polyg,aTrLoc,aloc);
TColStd_Array1OfInteger IndArr(1,polyg->NbNodes());
IndArr = polyg->Nodes();
const TColgp_Array1OfPnt& Nodes = aTrLoc->Nodes();
TColgp_Array1OfPnt TrLocPnts(1, Nodes.Length());
for ( Standard_Integer i = 1; i <= Nodes.Length(); i++)
TrLocPnts(i) = Nodes(i).Transformed(aloc);
for (int k=0; k<polyg->Nodes().Upper(); ++k)
{
e_pnt = TrLocPnts(IndArr.Value(k+1));
mP.x = (float) e_pnt.X();
mP.y = (float) e_pnt.Y();
mP.z = (float) e_pnt.Z();
meshIt = MeshMap.find(mP);
if (meshIt == MeshMap.end())
{
cout << "error2" << endl;
return false;
}
++MeanVec[meshIt->second.index];
// nehme stets den minimalen wert
if (((*edge_it).second[0])>((*meshIt).second).minCurv)
((*meshIt).second).minCurv = (*edge_it).second[0];
if ((*edge_it).second[1]<((*meshIt).second).maxCurv)
((*meshIt).second).maxCurv = (*edge_it).second[1];
}
}
// Knoten INNERHALB eines Faces die Offset-Werte zuweisen
for (unsigned int k=0; k<FacePntVector.size(); ++k)
{
meshIt = MeshMap.find(FacePntVector[k].pnt);
if (meshIt == MeshMap.end())
{
cout << "error3";
return false;
}
distSum = 0.0;
for (unsigned int l=0; l<FacePntVector[k].distances.size(); ++l)
distSum += FacePntVector[k].distances[l];
revSum = 0.0;
for (unsigned int l=0; l<FacePntVector[k].distances.size(); ++l)
{
revSum += distSum/FacePntVector[k].distances[l];
if (((*meshIt).second).minCurv == -1e+3)
((*meshIt).second).minCurv = 0.0;
if (((*meshIt).second).maxCurv == 1e+3)
((*meshIt).second).maxCurv = 0.0;
((*meshIt).second).minCurv += distSum*(FacePntVector[k].MinEdgeOff[l])/FacePntVector[k].distances[l];
((*meshIt).second).maxCurv += distSum*(FacePntVector[k].MaxEdgeOff[l])/FacePntVector[k].distances[l];
}
((*meshIt).second).minCurv /= revSum;
((*meshIt).second).maxCurv /= revSum;
}
FacePntVector.clear();
}
Base::Builder3D log,log3d;
Base::Vector3f pa,pb;
char text[10];
int w;
// übergebe krümmungswerte an m_MeshStruct
for (meshIt = MeshMap.begin(); meshIt != MeshMap.end(); ++meshIt)
{
w = meshIt->second.index;
m_MeshStruct[w].pnt = (*meshIt).first;
m_MeshStruct[w].minCurv = (((*meshIt).second).minCurv);
m_MeshStruct[w].maxCurv = (((*meshIt).second).maxCurv);
// Ausgabe
if (m_MeshStruct[w].maxCurv<10000000000)
{
snprintf(text,10,"%f",m_MeshStruct[w].minCurv);
//snprintf(text,10,"%i",w);
log.addText(m_MeshStruct[w].pnt.x, m_MeshStruct[w].pnt.y, m_MeshStruct[w].pnt.z,text);
}
if (MeanVec[w] == 1)
log3d.addSinglePoint(m_MeshStruct[w].pnt,4,0,0,0); // innere punkte - > schwarz
else if (MeanVec[w] == 2)
log3d.addSinglePoint(m_MeshStruct[w].pnt,4,1,1,1); // edge-punkte - > weiß
else
log3d.addSinglePoint(m_MeshStruct[w].pnt,4,1,0,0); // eck-punkte - > rot
//m_MeshStruct[w].minCurv = (((*meshIt).second).minCurv)/MeanVec[w];
//m_MeshStruct[w].maxCurv = (((*meshIt).second).maxCurv)/MeanVec[w];
//if(m_MeshStruct[w].maxCurv < 100 || fabs(m_MeshStruct[w].minCurv) < 100)
//{
// if(m_MeshStruct[w].maxCurv > fabs(m_MeshStruct[w].minCurv))
// {
// snprintf(text,10,"%f",m_MeshStruct[w].minCurv);
// //m_MeshStruct[w].normal.Scale(m_MeshStruct[w].minCurv,m_MeshStruct[w].minCurv,m_MeshStruct[w].minCurv);
// logo.addSingleArrow(m_MeshStruct[w].pnt, m_MeshStruct[w].pnt+m_MeshStruct[w].normal);
// }
// else
// {
// //snprintf(text,4,"%f",m_MeshStruct[w].maxCurv);
// m_MeshStruct[w].normal.Scale(m_MeshStruct[w].maxCurv,m_MeshStruct[w].maxCurv,m_MeshStruct[w].maxCurv);
// logo.addSingleArrow(m_MeshStruct[w].pnt, m_MeshStruct[w].pnt+m_MeshStruct[w].normal);
// }
//}
//if(m_MeshStruct[w].maxCurv < 100)
//{
// m_MeshStruct[w].normal.Scale(0.5*m_MeshStruct[w].maxCurv,0.5*m_MeshStruct[w].maxCurv,0.5*m_MeshStruct[w].maxCurv);
// logo.addSingleArrow(m_MeshStruct[w].pnt, m_MeshStruct[w].pnt+m_MeshStruct[w].normal);
//}*/
//snprintf(text,10,"%f",m_MeshStruct[w].maxCurv);
//snprintf(text,10,"%i",w);
/*if(m_MeshStruct[w].maxCurv > fabs(m_MeshStruct[w].minCurv))
{
snprintf(text,10,"%f",m_MeshStruct[w].minCurv);
}
else
{
snprintf(text,10,"%f",m_MeshStruct[w].maxCurv);
}*/
}
log.saveToFile("c:/printCurv.iv");
log3d.saveToFile("c:/triPnts.iv");
logo.saveToFile("c:/NormalsCurv.iv");
MeshPntsCad = m_CadMesh.GetPoints();
for (unsigned int j=0; j<m_FixFaces.size(); ++j)
{
TopoDS_Face aFace = TopoDS::Face(m_FixFaces[j]);
TransferFaceTriangulationtoFreeCAD(aFace, FaceMesh);
MeshPnts = FaceMesh.GetPoints();
MeshFacets2 = m_CadMesh.GetFacets();
MeshPntsCopy = MeshPnts;
n = MeshPnts.size();
TopLoc_Location aLocation;
// berechne normalen -> m_MeshStruct
Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);
const TColgp_Array1OfPnt& aNodes = aTr->Nodes();
// create array of node points in absolute coordinate system
TColgp_Array1OfPnt aPoints(1, aNodes.Length());
for ( Standard_Integer i = 1; i <= aNodes.Length(); i++)
aPoints(i) = aNodes(i).Transformed(aLocation);
const TColgp_Array1OfPnt2d& aUVNodes = aTr->UVNodes();
BRepAdaptor_Surface aSurface(aFace);
Base::Vector3f Pnt1, Pnt2;
gp_Pnt2d par;
gp_Pnt P;
gp_Vec D1U, D1V;
std::vector<bool> trans_check(m_MeshStruct.size(), false);
for (int i=1; i<n+1; ++i)
{
par = aUVNodes.Value(i);
aSurface.D1(par.X(),par.Y(),P,D1U,D1V);
P = aPoints(i);
Pnt1.x = (float) P.X();
Pnt1.y = (float) P.Y();
Pnt1.z = (float) P.Z();
meshIt = MeshMap.find(Pnt1);
if (meshIt == MeshMap.end())
{
cout << "error";
return false;
}
D1U.Cross(D1V);
D1U.Normalize();
if (aFace.Orientation() == TopAbs_FORWARD) D1U.Scale(-1.0);
int g = ((*meshIt).second).index;
D1U.Scale(0.1);
if(trans_check[g] == false)
{
m_dist_vec[g].x = - D1U.X();
m_dist_vec[g].y = - D1U.Y();
m_dist_vec[g].z = - D1U.Z();
MeshPntsCad[g].Set(MeshPntsCad[g].x - D1U.X(),
MeshPntsCad[g].y - D1U.Y(),
MeshPntsCad[g].z - D1U.Z());
(m_MeshStruct[g].pnt).Set(MeshPntsCad[g].x - D1U.X(),
MeshPntsCad[g].y - D1U.Y(),
MeshPntsCad[g].z - D1U.Z());
trans_check[g] = true;
}
}
}
m_CadMesh.Assign(MeshPntsCad, MeshFacets2);
return true;
}
bool SpringbackCorrection::Init()
{
m_EdgeStruct.clear();
EdgeMap.clear();
MeshMap.clear();
//Remove any existing Triangulation on the Shape
BRepTools::Clean(m_Shape);
best_fit::Tesselate_Shape(m_Shape,m_CadMesh,(float) 0.1); // Basistriangulierung des ganzen Shapes
MeshCore::MeshTopoAlgorithm algo(m_CadMesh);
algo.HarmonizeNormals();
MeshCore::MeshGeomFacet facet = m_CadMesh.GetFacet(0);
if (facet.GetNormal().z < 0.0)
algo.FlipNormals();
int n = m_CadMesh.CountFacets();
Base::Vector3f normal;
MeshCore::MeshPointArray points = m_CadMesh.GetPoints();
MeshCore::MeshFacetArray facets = m_CadMesh.GetFacets();
for (int i=0; i<n; ++i)
{
MeshCore::MeshGeomFacet face = m_CadMesh.GetFacet(i);
normal = face.GetNormal();
if (normal.z < 0.0)
{
facets[i].FlipNormal();
}
}
m_CadMesh.Assign(points, facets);
double max = cMin;
TopTools_IndexedDataMapOfShapeListOfShape anIndex;
anIndex.Clear();
TopExp aMap;
aMap.MapShapesAndAncestors(m_Shape,TopAbs_EDGE,TopAbs_FACE,anIndex);
TopExp_Explorer anExplorer, anExplorer2;
TopoDS_Face aFace;
EdgeStruct tempEdgeStruct;
std::vector<EdgeStruct> EdgeVec;
MeshCore::MeshKernel FaceMesh;
std::vector<double> curvature(2);
std::pair<TopoDS_Edge, std::vector<double> > aPair;
float maxOffset, minOffset;
for (anExplorer.Init(m_Shape,TopAbs_EDGE);anExplorer.More();anExplorer.Next())
{
tempEdgeStruct.aFace.clear();
tempEdgeStruct.MaxOffset = 1e+10;
tempEdgeStruct.MinOffset = -1e+10;
tempEdgeStruct.anEdge = TopoDS::Edge(anExplorer.Current()); // store current edge
const TopTools_ListOfShape& aFaceList = anIndex.FindFromKey(tempEdgeStruct.anEdge);
TopTools_ListIteratorOfListOfShape aListIterator;
for (aListIterator.Initialize(aFaceList);aListIterator.More(); aListIterator.Next())
{
// store corresponding faces
aFace = TopoDS::Face(aListIterator.Value());
tempEdgeStruct.aFace.push_back(aFace);
TransferFaceTriangulationtoFreeCAD(aFace, FaceMesh);
curvature = MeshCurvature(aFace, FaceMesh);
if (aFace.Orientation() == TopAbs_REVERSED)
{
maxOffset = (float) -curvature[1];
minOffset = (float) -curvature[0];
}
else
{
maxOffset = (float) curvature[0];
minOffset = (float) curvature[1];
}
if (maxOffset < tempEdgeStruct.MaxOffset)
tempEdgeStruct.MaxOffset = maxOffset;
if (minOffset > tempEdgeStruct.MinOffset)
tempEdgeStruct.MinOffset = minOffset;
}
if (tempEdgeStruct.MaxOffset > max)
curvature[1] = tempEdgeStruct.MaxOffset;
else
curvature[1] = cMin;
if (-tempEdgeStruct.MinOffset > max)
curvature[0] = tempEdgeStruct.MinOffset;
else
curvature[0] = -cMin;
aPair.first = tempEdgeStruct.anEdge;
aPair.second = curvature;
EdgeMap.insert(aPair);
}
return true;
}
bool SpringbackCorrection::Init_Setting(struct CuttingToolsSettings& set)
{
m_set = set;
return true;
}
bool SpringbackCorrection::SetFixEdges()
{
TopExp_Explorer anExplorer;
TopoDS_Edge anEdge;
std::map<TopoDS_Edge, std::vector<double>, Edge_Less>::iterator edge_it;
std::vector<double> pair(2,0.0);
for (unsigned int i=0; i<m_FixFaces.size(); ++i)
{
for (anExplorer.Init(m_FixFaces[i],TopAbs_EDGE); anExplorer.More(); anExplorer.Next())
{
anEdge = TopoDS::Edge(anExplorer.Current());
edge_it = EdgeMap.find(anEdge);
edge_it->second = pair;
}
}
return true;
}
bool SpringbackCorrection::TransferFaceTriangulationtoFreeCAD(const TopoDS_Face& aFace, MeshCore::MeshKernel& FaceMesh)
{
FaceMesh.Clear();
MeshCore::MeshBuilder builder(FaceMesh);
builder.Initialize(1000);
Base::Vector3f Points[3];
TopLoc_Location aLocation;
// takes the triangulation of the face aFace:
Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);
if (!aTr.IsNull()) // if this triangulation is not NULL
{
// takes the array of nodes for this triangulation:
const TColgp_Array1OfPnt& aNodes = aTr->Nodes();
// takes the array of triangles for this triangulation:
const Poly_Array1OfTriangle& triangles = aTr->Triangles();
// create array of node points in absolute coordinate system
TColgp_Array1OfPnt aPoints(1, aNodes.Length());
for ( Standard_Integer i = 1; i <= aNodes.Length(); i++)
aPoints(i) = aNodes(i).Transformed(aLocation);
// Takes the node points of each triangle of this triangulation.
// takes a number of triangles:
Standard_Integer nnn = aTr->NbTriangles();
Standard_Integer nt,n1,n2,n3;
for ( nt = 1 ; nt < nnn+1 ; nt++)
{
// takes the node indices of each triangle in n1,n2,n3:
triangles(nt).Get(n1,n2,n3);
// takes the node points:
gp_Pnt aPnt1 = aPoints(n1);
Points[0].Set(float(aPnt1.X()),float(aPnt1.Y()),float(aPnt1.Z()));
gp_Pnt aPnt2 = aPoints(n2);
Points[1].Set((float) aPnt2.X(),(float) aPnt2.Y(),(float) aPnt2.Z());
gp_Pnt aPnt3 = aPoints(n3);
Points[2].Set((float) aPnt3.X(),(float) aPnt3.Y(),(float) aPnt3.Z());
// give the occ faces to the internal mesh structure of freecad
MeshCore::MeshGeomFacet Face(Points[0],Points[1],Points[2]);
builder.AddFacet(Face);
}
}
// if the triangulation of only one face is not possible to get
else
{
throw Base::Exception("Empty face triangulation\n");
}
// finish FreeCAD Mesh Builder and exit with new mesh
builder.Finish();
return true;
}
/*
MeshCore::MeshKernel SpringbackCorrection::BuildMesh(Handle_Poly_Triangulation aTri, std::vector<Base::Vector3f> TrPoints)
{
MeshCore::MeshKernel FaceMesh;
MeshCore::MeshBuilder builder(FaceMesh);
builder.Initialize(1000);
Base::Vector3f Points[3];
const Poly_Array1OfTriangle& triangles = aTri->Triangles();
Standard_Integer nnn = aTri->NbTriangles();
Standard_Integer nt,n1,n2,n3;
for ( nt = 1 ; nt < nnn+1 ; nt++)
{
// takes the node indices of each triangle in n1,n2,n3:
triangles(nt).Get(n1,n2,n3);
// takes the node points:
Points[0] = TrPoints[n1];
Points[1] = TrPoints[n2];
Points[2] = TrPoints[n3];
// give the occ faces to the internal mesh structure of freecad
MeshCore::MeshGeomFacet Face(Points[0],Points[1],Points[2]);
builder.AddFacet(Face);
}
// finish FreeCAD Mesh Builder and exit with new mesh
builder.Finish();
return FaceMesh;
}
*/
int SpringbackCorrection::GetBoundary(const MeshCore::MeshKernel &mesh, MeshCore::MeshPointArray &meshPnts)
{
// get mesh-boundary
// zweck: nur für die inneren punkte wird der curvature wert über die edge abstände berechnet
std::list< std::vector <unsigned long> > BoundariesIndex;
std::list< std::vector <unsigned long> >::iterator bInd;
MeshCore::MeshAlgorithm algo(mesh);
algo.GetMeshBorders(BoundariesIndex);
//Set all MeshPoints to Property 0
for (unsigned int i=0;i<meshPnts.size();++i)
meshPnts[i].SetProperty(0);
//Set Boundary Points to 1
int inner_points = 0;
for (bInd = BoundariesIndex.begin(); bInd != BoundariesIndex.end(); ++bInd)
{
for (unsigned int i=0;i< bInd->size();++i)
{
meshPnts[(*bInd).at(i)].SetProperty(1);
}
}
for (unsigned int i=0;i<meshPnts.size();++i)
{
if (meshPnts[i]._ulProp == 0)
inner_points++;
}
return (inner_points);
}
/*
bool SpringbackCorrection::SmoothCurvature()
{
MeshCore::MeshPointIterator v_it(m_Mesh);
MeshCore::MeshRefPointToPoints vv_it(m_Mesh);
std::set<MeshCore::MeshPointArray::_TConstIterator> PntNei;
std::set<MeshCore::MeshPointArray::_TConstIterator>::iterator pnt_it;
int n = m_MeshStruct.size();
std::vector<double> SCMax(n);
std::vector<double> SCMin(n);
double maxCurv = 0.0, minCurv = 0.0;
for (v_it.Begin(); v_it.More(); v_it.Next())
{
PntNei = vv_it[v_it.Position()];
maxCurv += m_MeshStruct[v_it.Position()].maxCurv;
minCurv += m_MeshStruct[v_it.Position()].minCurv;
for (pnt_it = PntNei.begin(); pnt_it !=PntNei.end(); ++pnt_it)
{
maxCurv += m_MeshStruct[(*pnt_it)[0]._ulProp].maxCurv;
minCurv += m_MeshStruct[(*pnt_it)[0]._ulProp].minCurv;
}
SCMax[v_it.Position()] = maxCurv/(PntNei.size()+1);
SCMin[v_it.Position()] = minCurv/(PntNei.size()+1);
maxCurv = 0.0;
minCurv = 0.0;
}
for (int i=0; i<n; ++i)
{
m_MeshStruct[i].maxCurv = SCMax[i];
m_MeshStruct[i].minCurv = SCMin[i];
}
return true;
}
*/
bool SpringbackCorrection::SmoothMesh(MeshCore::MeshKernel &Mesh, double d_max)
{
Base::Builder3D log;
MeshCore::MeshKernel localMesh, Meshtmp;
MeshCore::MeshPoint mpnt, spnt;
MeshCore::MeshPointArray locPointArray, PointArray = Mesh.GetPoints();
MeshCore::MeshFacetArray locFacetArray, FacetArray = Mesh.GetFacets();
MeshCore::MeshPointIterator v_it(Mesh);
MeshCore::MeshRefPointToPoints vv_it(Mesh);
std::set<unsigned long>::const_iterator pnt_it;
MeshCore::MeshPointArray::_TConstIterator v_beg = Mesh.GetPoints().begin();
Base::Vector3f N, L, coor;
int n = m_MeshStruct.size();
int g;
for (v_it.Begin(); v_it.More(); v_it.Next())
{
g = v_it.Position();
spnt.Set(0.0, 0.0, 0.0);
locPointArray.push_back(*v_it);
spnt += *v_it;
const std::set<unsigned long>& PntNei = vv_it[(*v_it)._ulProp];
if (PntNei.size() < 3)
continue;
for (pnt_it = PntNei.begin(); pnt_it !=PntNei.end(); ++pnt_it)
{
locPointArray.push_back(v_beg[*pnt_it]);
spnt += v_beg[*pnt_it];
}
spnt.Scale((float) (1.0/(double(PntNei.size()) + 1.0)),(float) (1.0/(double(PntNei.size()) + 1.0)),(float) (1.0/(double(PntNei.size()) + 1.0)));
localMesh.Assign(locPointArray, locFacetArray);
// need at least one facet to perform the PCA
MeshCore::MeshGeomFacet face;
face._aclPoints[0] = locPointArray[0];
face._aclPoints[1] = locPointArray[1];
face._aclPoints[2] = locPointArray[2];
localMesh.AddFacet(face);
MeshCore::MeshEigensystem pca(localMesh);
pca.Evaluate();
Base::Matrix4D T1 = pca.Transform();
N.x = (float) T1[0][0];
N.y = (float) T1[0][1];
N.z = (float) T1[0][2];
L.Set(v_it->x - spnt.x, v_it->y - spnt.y, v_it->z - spnt.z);
N.Normalize();
if (N*L < 0.0)
N.Scale(-1.0, -1.0, -1.0);
if ((*v_it)._ulProp == 2286)
{
log.addSinglePoint(spnt,4,1,0,0);
log.addSinglePoint(*v_it,4,0,0,0);
for (unsigned int i=0; i<locPointArray.size(); ++i)
log.addSinglePoint(locPointArray[i],4);
for (int i=0; i<3; ++i)
{
coor.x = (float) T1[i][0];
coor.y = (float) T1[i][1];
coor.z = (float) T1[i][2];
coor.Normalize();
log.addSingleArrow(*v_it, *v_it + coor);
}
/*log.addSingleArrow(*v_it, *v_it - N);
snprintf(text,10,"%i",(*v_it)._ulProp);
log.addText(v_it->x, v_it->y, v_it->z,text);*/
}
double d = d_max;
if (fabs(N*L)< d_max) d = fabs(N*L);
N.Scale((float) d,(float) d,(float) d);
PointArray[v_it.Position()].Set(v_it->x - N.x, v_it->y - N.y, v_it->z - N.z);
locPointArray.clear();
localMesh = Meshtmp;
}
Mesh.Assign(PointArray, FacetArray);
log.saveToFile("c:/checkNormals.iv");
return true;
}
bool SpringbackCorrection::SmoothMesh(MeshCore::MeshKernel &Mesh, std::vector<int> ind, double d_max)
{
Base::Builder3D log;
MeshCore::MeshKernel localMesh, Meshtmp;
MeshCore::MeshPoint mpnt, spnt;
MeshCore::MeshPointArray locPointArray, PointArray = Mesh.GetPoints();
MeshCore::MeshFacetArray locFacetArray, FacetArray = Mesh.GetFacets();
MeshCore::MeshPointIterator v_it(Mesh);
MeshCore::MeshRefPointToPoints vv_it(Mesh);
std::set<unsigned long>::const_iterator pnt_it;
MeshCore::MeshPointArray::_TConstIterator v_beg = Mesh.GetPoints().begin();
Base::Vector3f N, L, coor;
int n = ind.size();
for (int i=0; i<n; ++i)
{
v_it.Set(ind[i]);
spnt.Set(0.0, 0.0, 0.0);
locPointArray.push_back(*v_it);
spnt += *v_it;
const std::set<unsigned long>& PntNei = vv_it[(*v_it)._ulProp];
if (PntNei.size() < 3)
continue;
for (pnt_it = PntNei.begin(); pnt_it !=PntNei.end(); ++pnt_it)
{
locPointArray.push_back(v_beg[*pnt_it]);
spnt += v_beg[*pnt_it];
}
spnt.Scale((float) (1.0/(double(PntNei.size()) + 1.0)),(float) (1.0/(double(PntNei.size()) + 1.0)),(float) (1.0/(double(PntNei.size()) + 1.0)));
localMesh.Assign(locPointArray, locFacetArray);
// need at least one facet to perform the PCA
MeshCore::MeshGeomFacet face;
face._aclPoints[0] = locPointArray[0];
face._aclPoints[1] = locPointArray[1];
face._aclPoints[2] = locPointArray[2];
localMesh.AddFacet(face);
MeshCore::MeshEigensystem pca(localMesh);
pca.Evaluate();
Base::Matrix4D T1 = pca.Transform();
N.x = (float) T1[0][0];
N.y = (float) T1[0][1];
N.z = (float) T1[0][2];
L.Set(v_it->x - spnt.x, v_it->y - spnt.y, v_it->z - spnt.z);
N.Normalize();
if (N*L < 0.0)
N.Scale(-1.0, -1.0, -1.0);
if ((*v_it)._ulProp == 2286)
{
log.addSinglePoint(spnt,4,1,0,0);
log.addSinglePoint(*v_it,4,0,0,0);
for (unsigned int i=0; i<locPointArray.size(); ++i)
log.addSinglePoint(locPointArray[i],4);
for (int i=0; i<3; ++i)
{
coor.x = (float) T1[i][0];
coor.y = (float) T1[i][1];
coor.z = (float) T1[i][2];
coor.Normalize();
log.addSingleArrow(*v_it, *v_it + coor);
}
/*log.addSingleArrow(*v_it, *v_it - N);
snprintf(text,10,"%i",(*v_it)._ulProp);
log.addText(v_it->x, v_it->y, v_it->z,text);*/
}
double d = d_max;
if (fabs(N*L)< d_max) d = fabs(N*L);
N.Scale((float) d,(float) d,(float) d);
PointArray[v_it.Position()].Set(v_it->x - N.x, v_it->y - N.y, v_it->z - N.z);
locPointArray.clear();
localMesh = Meshtmp;
}
Mesh.Assign(PointArray, FacetArray);
log.saveToFile("c:/checkNormals.iv");
return true;
}
/*
bool SpringbackCorrection::GetFaceAng(MeshCore::MeshKernel &mesh, int deg_tol)
{
Base::Vector3f normal, base;
double deg;
int n = mesh.CountFacets();
bool b = true;
for (int i=0; i<n; ++i)
{
MeshCore::MeshGeomFacet face = mesh.GetFacet(i);
face.CalcNormal();
normal = face.GetNormal();
normal.Normalize();
base = normal;
base.z = 0.0;
base.Normalize();
if (normal.z < 0.0)
deg = 90.0 + acos(normal*base)*180.0/PI;
else
deg = 90.0 - acos(normal*base)*180.0/PI;
if (deg > deg_tol)
b = false;
m_FaceAng.push_back(deg);
}
return b;
}
*/
std::vector<int> SpringbackCorrection::InitFaceCheck(MeshCore::MeshKernel &mesh, int degree)
{
std::vector<int> faceInd;
double tol = degree;
double alpha;
MeshCore::MeshFacetIterator fIt(mesh);
MeshCore::MeshPointIterator mIt(mesh);
MeshCore::MeshRefPointToFacets p2fIt(mesh);
Base::Vector3f normal, base, gpnt;
Base::Builder3D log;
MeshCore::MeshPointArray mPnts = mesh.GetPoints();
MeshCore::MeshFacetArray mFacets = mesh.GetFacets();
MeshCore::MeshFacetArray::_TConstIterator f_beg = mesh.GetFacets().begin();
int n = mesh.CountFacets();
for (int i=0; i<n; ++i)
{
MeshCore::MeshGeomFacet face = mesh.GetFacet(i);
//face.CalcNormal();
normal = face.GetNormal();
normal.Normalize();
base = normal;
base.z = 0.0;
base.Normalize();
gpnt = face.GetGravityPoint();
if (normal.z < 0.0)
{
alpha = 90.0 + acos(normal*base)*180.0/PI;
//log.addSingleArrow(gpnt,gpnt+normal,6,1,0,0);
}
else
{
alpha = 90.0 - acos(normal*base)*180.0/PI;
//log.addSingleArrow(gpnt,gpnt+normal);
}
if (alpha > tol)
{
// markiere kritisches face
mFacets[i].SetProperty(0);
for (int j=0; j<3; ++j)
{
const std::set<unsigned long>& faceSet = p2fIt[mFacets[i]._aulPoints[j]];
for (std::set<unsigned long>::const_iterator it = faceSet.begin(); it != faceSet.end(); ++it)
{
f_beg[*it].SetProperty(5);
}
}
log.addSingleArrow(gpnt,gpnt+normal,4,1,0,0);
}
else
{
mFacets[i].SetProperty(1);
faceInd.push_back(i);
}
}
log.saveToFile("c:/normalschecker.iv");
MeshCore::MeshFacetArray mFacets2 = mesh.GetFacets();
for (unsigned int i=0; i<mFacets2.size(); ++i)
{
if (mFacets2[i]._ulProp == 5)
{
mFacets[i].SetProperty(0);
}
}
mesh.Assign(mPnts, mFacets);
log.saveToFile("c:/angles.iv");
return faceInd;
}
std::vector<int> SpringbackCorrection::FaceCheck(MeshCore::MeshKernel &mesh, int degree)
{
std::vector<int> faceInd;
double tol = degree;
double alpha;
MeshCore::MeshFacetIterator fIt(mesh);
MeshCore::MeshPointIterator mIt(mesh);
Base::Vector3f normal, base, gpnt;
Base::Builder3D log;
MeshCore::MeshPointArray mPnts = mesh.GetPoints();
MeshCore::MeshFacetArray mFacets = mesh.GetFacets();
int n = mesh.CountFacets();
for (int i=0; i<n; ++i)
{
MeshCore::MeshGeomFacet face = mesh.GetFacet(i);
face.CalcNormal();
normal = face.GetNormal();
normal.Normalize();
base = normal;
base.z = 0.0;
base.Normalize();
gpnt = face.GetGravityPoint();
if (normal.z < 0.0)
{
alpha = 90.0 + acos(normal*base)*180.0/PI;
log.addSingleArrow(gpnt,gpnt+normal,2,1,0,0);
}
else
alpha = 90.0 - acos(normal*base)*180.0/PI;
if (alpha > tol)
{
faceInd.push_back(i);
cout << "i: " << i << ", angle: " << alpha << endl;
}
}
log.saveToFile("c:/angles.iv");
return faceInd;
}
/*
bool SpringbackCorrection::CorrectScale(double zLim)
{
// VERSCHIEBUNGSVEKTOREN ...
// berechnung der skalierungsfaktoren bzgl. der Cad-Normalen
int n = m_CadMesh.CountPoints();
double zLev;
for (int i=0; i<n; ++i)
{
m_MeshStruct[i].normal.Normalize();
zLev = m_MeshStruct[i].pnt.z + m_Offset[i]*m_MeshStruct[i].normal.z;
if (zLev>zLim)
m_Offset[i] = (zLim - m_MeshStruct[i].pnt.z)/m_MeshStruct[i].normal.z;
}
return true;
}
*/
bool SpringbackCorrection::Perform(int deg_Tol, bool out)
{
unsigned int NumRef;
std::vector<double> dist_vec;
//GetFaceAng(m_CadMesh, deg_Tol+1);
//cout << "Init" << endl;
//Init(); // tesseliere shape -> Basistriangulierung CAD-Mesh
// EdgeMap wird hier gefüllt
Base::Vector3f nullvec(0.0,0.0,0.0);
m_dist_vec.resize(m_CadMesh.CountPoints(), nullvec); // fülle mit Nullvektoren
cout << "SetFixEdges" << endl;
SetFixEdges();
const MeshCore::MeshKernel RefMesh23 = m_CadMesh;
cout << "CalcCurv" << endl;
if (!CalcCurv())
return false;
// berechne Krümmungswerte über Edgekrümmungen
// MeshMap wird hier gefüllt
const MeshCore::MeshKernel RefMesh = m_CadMesh; // übegebe CAD-Mesh vor der Verformung
/*Base::Builder3D log;
Base::Vector3f gpnt, normal;
int numb = m_CadMesh.CountFacets();
for (int i=0; i<numb; ++i)
{
MeshCore::MeshGeomFacet face = m_CadMesh.GetFacet(i);
normal = face.GetNormal();
if(normal.z < 0.0)
log.saveToFile("c:/didid.iv");
gpnt = face.GetGravityPoint();
normal.Scale(10,10,10);
log.addSingleArrow(gpnt,gpnt+normal);
}
log.saveToFile("c:/Facenormals.iv");*/
// speichere normalen seperat
m_normals.clear();
m_normals.resize(m_MeshStruct.size());
//Base::Builder3D logo;
for (unsigned int i=0; i<m_normals.size(); ++i)
{
m_normals[i] = m_MeshStruct[i].normal; // Normale am Punkt i der Basistriangulierung
//logo.addSingleArrow(m_MeshStruct[i].pnt, m_MeshStruct[i].pnt + m_normals[i]);
}
//logo.saveToFile("c:/normals.iv");
// übergebe Normalen und CAD-Mesh für Fehlerberechnng
best_fit befi;
befi.m_normals = m_normals;
befi.m_CadMesh = m_CadMesh;
m_error.resize(m_CadMesh.CountPoints(), 0.0);
for(unsigned int i=0; i<m_MeshVec.size(); ++i)
{
befi.CompTotalError(m_MeshVec[i]); // Fehlerberechnung
}
// VERSCHIEBUNGSVEKTOREN ...
// berechnung der skalierungsfaktoren bzgl. der Cad-Normalen
int n = m_CadMesh.CountPoints();
for (int i=0; i<n; ++i)
{
m_MeshStruct[i].error = befi.m_error[i];
if (m_MeshStruct[i].error < 0)
{
if ((m_MeshStruct[i].maxCurv - m_set.master_radius) < 0.0)
m_Offset.push_back(0.0);
else if (-m_MeshStruct[i].error > (m_MeshStruct[i].maxCurv - m_set.master_radius))
m_Offset.push_back(m_MeshStruct[i].maxCurv - m_set.master_radius);
else
m_Offset.push_back(-m_MeshStruct[i].error);
}
else
{
if ((m_MeshStruct[i].minCurv + m_set.slave_radius) > 0.0)
m_Offset.push_back(0.0);
else if (m_MeshStruct[i].error > -(m_MeshStruct[i].minCurv + m_set.slave_radius))
m_Offset.push_back(m_MeshStruct[i].minCurv + m_set.slave_radius);
else
m_Offset.push_back(-m_MeshStruct[i].error);
}
}
//Base::BoundBox3f bbox = m_CadMesh.GetBoundBox(); // hole bounding-box
//CorrectScale(bbox.MaxZ); // korrigiere verschiebungsvektoren...
//m_set.correction_factor = -0.1;
// skalierung der Cad-Normalen
for (int i=0; i<n; ++i)
{
m_normals[i].Scale((float) (m_set.correction_factor*m_Offset[i]),
(float) (m_set.correction_factor*m_Offset[i]),
(float) (m_set.correction_factor*m_Offset[i]));
}
for(int i=0; i<m_normals.size(); ++i)
{
m_dist_vec[i] = m_normals[i];
}
if(out==true) //hier werden die Outputvektoren für Catia geschrieben
{
MeshCore::MeshPointArray mpts = RefMesh23.GetPoints();
Base::Builder3D loo;
ofstream anOutputFile;
anOutputFile.open("c:/catia_offset.txt");
anOutputFile.precision(7);
for(int i=0; i< mpts.size(); ++i)
{
loo.addSingleArrow(mpts[i], mpts[i] + m_dist_vec[i]);
anOutputFile << mpts[i].x << " " << mpts[i].y << " " << mpts[i].z << " " << m_dist_vec[i].x << " " << m_dist_vec[i].y << " " << m_dist_vec[i].z << endl;
}
loo.saveToFile("c:/prpopo.iv");
anOutputFile.close();
return true; //mehr braucne wir auch nicht....
}
std::vector<int> tmpVec;
tmpVec = FaceCheck(m_CadMesh, deg_Tol+1);
NumRef = (int) tmpVec.size();
MeshCore::MeshPointArray pntAr = m_CadMesh.GetPoints();
MeshCore::MeshFacetArray facAr = m_CadMesh.GetFacets();
// Spiegelung
Base::Builder3D log3d;
for (int i=0; i<n; ++i)
{
log3d.addSingleArrow(pntAr[i], pntAr[i] + m_normals[i]);
pntAr[i].Set(pntAr[i].x + m_normals[i].x, pntAr[i].y + m_normals[i].y, pntAr[i].z + m_normals[i].z);
}
log3d.saveToFile("c:/project2result.iv");
m_CadMesh.Assign(pntAr, facAr);
//std::vector<int> tmpVec;
std::vector<Base::Vector3f> normalsRef = m_normals;
int cc = 0;
// ********************************** GLOBALE KORREKTUR ****************************************
int cm = 49;
InitFaceCheck(m_CadMesh, deg_Tol+1); // kritische dreiecke -> _ulProp = 0
MeshCore::MeshFacetArray facAr2 = m_CadMesh.GetFacets();
while (true)
{
tmpVec = FaceCheck(m_CadMesh, deg_Tol+1);
cout << "remaining: " << tmpVec.size() << endl;
if (tmpVec.size() == NumRef || cm == 0)
{
cout << cm << "left" << endl;
break;
}
--cm;
MeshCore::MeshPointArray pntAr2 = RefMesh.GetPoints();
for (unsigned int i=0; i<pntAr2.size(); ++i)
{
m_normals[i].Normalize();
m_normals[i].Scale((cm*normalsRef[i].Length())/50,(cm*normalsRef[i].Length())/50, (cm*normalsRef[i].Length())/50);
pntAr2[i].Set(pntAr2[i].x + m_normals[i].x, pntAr2[i].y + m_normals[i].y, pntAr2[i].z + m_normals[i].z);
}
m_CadMesh.Assign(pntAr2, facAr2);
}
for(int i=0; i< m_normals.size(); ++i)
{
m_dist_vec[i] += m_normals[i];
}
// *********************** REGION-GROWING **********************
MeshCore::MeshFacetArray mFacets = m_CadMesh.GetFacets();
MeshCore::MeshPointArray mPoints = m_CadMesh.GetPoints();
int num = mFacets.size();
for (int i=0; i<num; ++i) mFacets[i].ResetFlag(MeshCore::MeshFacet::VISIT); // lösche alle VISIT-Flags
m_RingCurrent = 0;
std::vector<unsigned long> aRegion;
std::vector< std::pair<unsigned long, double> > skals;
std::vector< std::vector< std::pair<unsigned long, double> > > RegionSkals;
MeshCore::MeshBuilder builder(m_Mesh_vis);
builder.Initialize(10000);
MeshCore::MeshBuilder builder2(m_Mesh_vis2);
builder2.Initialize(10000);
for (int i=0; i<num; ++i)
{
cout << i << " von " << num << endl;
for (int m=0; m<num; ++m)
{
if (mFacets[m]._ulProp == 0)
{
mFacets[m].SetFlag(MeshCore::MeshFacet::VISIT); // kritische faces kriegen ein visit-flag gesetzt
}
}
if (mFacets[i]._ulProp == 0)
{
MeshCore::MeshGeomFacet Face(mPoints[mFacets[i]._aulPoints[0]],
mPoints[mFacets[i]._aulPoints[1]],
mPoints[mFacets[i]._aulPoints[2]]);
builder.AddFacet(Face);
}
else
{
MeshCore::MeshGeomFacet Face2(mPoints[mFacets[i]._aulPoints[0]],
mPoints[mFacets[i]._aulPoints[1]],
mPoints[mFacets[i]._aulPoints[2]]);
builder2.AddFacet(Face2);
}
m_CadMesh.Assign(mPoints, mFacets);
cout << "a" << endl;
if (mFacets[i]._ulProp == 1 && !mFacets[i].IsFlag(MeshCore::MeshFacet::VISIT)) // falls unkritisches facet
// welches noch nicht einer region zugewiesen wurde
{
cout << "b" << endl;
m_RingVector.clear();
m_RingVector.push_back(i);
m_RegionVector.push_back(m_RingVector);
m_RingVector.clear();
m_RingCurrent = 0;
m_CadMesh.VisitNeighbourFacets(*this,i);
for (unsigned int j=0; j<m_RegionVector.size(); ++j)
{
cout << "c" << endl;
for (unsigned int k=0; k<m_RegionVector[j].size(); ++k)
{
aRegion.push_back(m_RegionVector[j][k]);
}
}
/*Base::Vector3f pnt1(0,0,0);
Base::Vector3f pnt2(1,0,0);
Base::Vector3f pnt3(0,1,0);
MeshCore::MeshGeomFacet Face(pnt1,pnt2,pnt3);
builder.AddFacet(Face);*/
m_Regions.push_back(aRegion);
for (int l=0; l<num; ++l) mFacets[l]._ucFlag = 0;
cout << "d" << endl;
for (unsigned int l=0; l<m_Regions.size(); ++l)
for (unsigned int m=0; m<m_Regions[l].size(); ++m)
mFacets[m_Regions[l][m]].SetFlag(MeshCore::MeshFacet::VISIT);
skals = RegionEvaluate(m_CadMesh, aRegion, normalsRef);
RegionSkals.push_back(skals);
skals.clear();
m_RegionVector.clear();
aRegion.clear();
cout << "e" << endl;
}
}
builder.Finish();
builder2.Finish();
cout << "fast" << endl;
Base::Builder3D logg;
double d;
// stelle die regionen dar
for (unsigned int i=0; i<RegionSkals.size(); ++i)
{
cout << i << endl;
d = double(i)/double(RegionSkals.size()-1.0);
cout << d << endl;
for (unsigned int j=0; j<RegionSkals[i].size(); ++j)
{
logg.addSinglePoint((float) mPoints[RegionSkals[i][j].first].x,
(float) mPoints[RegionSkals[i][j].first].y,
(float) mPoints[RegionSkals[i][j].first].z,3,(float) d,(float) d,(float) d);
}
}
logg.saveToFile("c:/regions.iv");
/*
// hole rand der regionen
MeshCore::MeshRefPointToFacets p2fIt(tmpMesh);
for(int i=0; i<m_Regions[0].size(); ++i)
{
for(int j=0; j<3; ++j)
{
std::set<MeshCore::MeshFacetArray::_TConstIterator>& faceSet = p2fIt[m_Regions[0][i]._aulPoints[j]];
for (std::set<MeshCore::MeshFacetArray::_TConstIterator>::const_iterator it = faceSet.begin(); it != faceSet.end(); ++it)
{
if((*it)[0]._ulProp == 0)
m_RegionBounds.push_back((*it)[0]);
}
}
}*/
tmpVec = InitFaceCheck(m_CadMesh, deg_Tol+1);
cout << " glob: " << tmpVec.size() << endl;
// ********************************** LOKALE KORREKTUR ****************************************
unsigned long ind;
MeshCore::MeshPointArray tmpPnts = m_CadMesh.GetPoints();
MeshCore::MeshFacetArray tmpFact = m_CadMesh.GetFacets();
Base::Builder3D logic;
int cm_ref = 50-cm;
for (unsigned int i=0; i<RegionSkals.size(); ++i)
{
cm = cm_ref;
while (true)
{
tmpVec = FaceCheck(m_CadMesh, deg_Tol+1);
cout << "remaining: " << tmpVec.size() << endl;
if (tmpVec.size() > NumRef || cm == 0)
{
tmpPnts = m_CadMesh.GetPoints();
for (unsigned int k=0; k<tmpVec.size(); ++k)
{
for (int l=0; l<3; ++l)
{
logic.addSinglePoint(tmpPnts[tmpFact[tmpVec[k]]._aulPoints[l]].x,
tmpPnts[tmpFact[tmpVec[k]]._aulPoints[l]].y,
tmpPnts[tmpFact[tmpVec[k]]._aulPoints[l]].z,5,0,0,1);
}
}
logic.saveToFile("c:/tired.iv");
for (unsigned int j=0; j<RegionSkals[i].size(); ++j)
{
ind = RegionSkals[i][j].first;
m_normals[ind].Normalize();
m_normals[ind].Scale(-normalsRef[ind].Length()/50,
-normalsRef[ind].Length()/50,
-normalsRef[ind].Length()/50);
tmpPnts[ind].Set(tmpPnts[ind].x + m_normals[ind].x,
tmpPnts[ind].y + m_normals[ind].y,
tmpPnts[ind].z + m_normals[ind].z);
m_dist_vec[ind] += m_normals[ind];
}
m_CadMesh.Assign(tmpPnts, tmpFact);
break;
}
tmpPnts = m_CadMesh.GetPoints();
for (unsigned int j=0; j<RegionSkals[i].size(); ++j)
{
ind = RegionSkals[i][j].first;
m_normals[ind].Normalize();
m_normals[ind].Scale((normalsRef[ind].Length())/50,
(normalsRef[ind].Length())/50,
(normalsRef[ind].Length())/50);
tmpPnts[ind].Set(tmpPnts[ind].x + m_normals[ind].x,
tmpPnts[ind].y + m_normals[ind].y,
tmpPnts[ind].z + m_normals[ind].z);
m_dist_vec[ind] += m_normals[ind];
}
m_CadMesh.Assign(tmpPnts, tmpFact);
--cm;
}
}
//SmoothMesh(m_CadMesh, 50);
//SmoothMesh(m_CadMesh, 50);
/*SmoothMesh(m_CadMesh, 50);
SmoothMesh(m_CadMesh, 50);
SmoothMesh(m_CadMesh, 50);
SmoothMesh(m_CadMesh, 50);
SmoothMesh(m_CadMesh, 50);
SmoothMesh(m_CadMesh, 50);*/
// MeshCore::MeshPointArray mpts = RefMesh23.GetPoints();
//Base::Builder3D loooo;
//ofstream anOutputFile;
//anOutputFile.open("c:/catia_offset.txt");
// anOutputFile.precision(7);
//for(int i=0; i< mpts.size(); ++i)
//{
// loooo.addSingleArrow(mpts[i], mpts[i] + m_dist_vec[i]);
// anOutputFile << mpts[i].x << " " << mpts[i].y << " " << mpts[i].z << " " << m_dist_vec[i].x << " " << m_dist_vec[i].y << " " << m_dist_vec[i].z << endl;
//}
//loooo.saveToFile("c:/prpopo.iv");
// anOutputFile.close();
//anOutputFile <<
return true;
}
std::vector< std::pair<unsigned long, double> > SpringbackCorrection::RegionEvaluate(const MeshCore::MeshKernel &mesh, std::vector<unsigned long> &RegionFacets, std::vector<Base::Vector3f> &normals)
{
std::list< std::vector <Base::Vector3f> > Borders;
std::list< std::vector <Base::Vector3f> >::iterator bIt;
std::map <unsigned long, Base::Vector3f> RegionMap;
std::map <unsigned long, Base::Vector3f>::iterator rIt;
std::map <double, unsigned long> DistMap;
std::map <double, unsigned long>::iterator dIt;
std::pair<unsigned long, Base::Vector3f> Ind2Pnt;
std::pair<double, unsigned long> Dist2Ind;
std::vector< std::pair<double, unsigned long> > dists;
std::vector< std::pair< unsigned long, double> > skals;
MeshCore::MeshAlgorithm algo(mesh); // übergebe mesh
algo.GetFacetBorders(RegionFacets, Borders); // speichert ränder der region in Borders
MeshCore::MeshFacetArray facets = mesh.GetFacets();
MeshCore::MeshPointArray points = mesh.GetPoints();
// um doppelte indizes zu vermeiden push die punkte der region in eine map
for (unsigned int i=0; i<RegionFacets.size(); ++i)
{
for (int j=0; j<3; ++j)
{
Ind2Pnt.first = facets[RegionFacets[i]]._aulPoints[j];
Ind2Pnt.second = points[Ind2Pnt.first];
RegionMap.insert(Ind2Pnt);
}
}
// berechne distanzen der regionenpunkte zu den rändern
Base::Vector3f distVec; // speichert abstandsvektor
double distVal; // speichert maximalen abstandswert zum rand
for (rIt = RegionMap.begin(); rIt != RegionMap.end(); ++rIt)
{
distVal = 1e+3;
for (bIt = Borders.begin(); bIt != Borders.end(); ++bIt)
{
for (unsigned int i=0; i< bIt->size(); ++i)
{
distVec = (*rIt).second - (*bIt).at(i);
if (distVec.Length() < distVal)
distVal = distVec.Length();
}
}
Dist2Ind.first = distVal;
Dist2Ind.second = (*rIt).first;
dists.push_back(Dist2Ind);
DistMap.insert(Dist2Ind);
}
dIt = DistMap.end();
--dIt;
double d_max = (*dIt).first;
std::pair<unsigned long, double> pair;
for (unsigned int i=0; i<dists.size(); ++i)
{
pair.first = dists[i].second;
if (dists[i].first != 0.0)
pair.second = ( (cos( ((dists[i].first * PI) / d_max) - PI) + 1) / 2); // 0.5 * [ cos( (dist * PI / dist_max) - PI ) + 1 ]
else
pair.second = 0.0;
skals.push_back(pair);
normals[pair.first].Scale((float) pair.second, (float) pair.second, (float) pair.second);
}
return skals;
}
bool SpringbackCorrection::FacetRegionGrowing(MeshCore::MeshKernel &mesh,
std::vector<MeshCore::MeshFacet> &FacetRegion,
MeshCore::MeshFacetArray &mFacets)
{
MeshCore::MeshRefFacetToFacets ff_It(mesh);
MeshCore::MeshFacet facet = FacetRegion.back();
const std::set<unsigned long>& FacetNei = ff_It[facet._ulProp];
MeshCore::MeshFacetArray::_TConstIterator f_beg = mesh.GetFacets().begin();
std::set<unsigned long>::const_iterator f_it;
for (f_it = FacetNei.begin(); f_it != FacetNei.end(); ++f_it)
{
if (f_beg[*f_it]._ucFlag == MeshCore::MeshFacet::VISIT)
{
FacetRegion.push_back(f_beg[*f_it]);
mFacets[f_beg[*f_it]._ulProp].SetFlag(MeshCore::MeshFacet::INVALID); // markiere als schon zugewiesen
FacetRegionGrowing(mesh, FacetRegion, mFacets);
}
}
return true;
}
//
//bool SpringbackCorrection::Init()
//{
// Base::Builder3D log;
// Base::Vector3f p1,p2;
// double curv;
// // Triangulate Shape (vorläufig)
// best_fit::Tesselate_Shape(m_Shape, m_Mesh, 1);
//
// MeshCurvature(m_Mesh);
//
// std::vector<Base::Vector3f> normals = best_fit::Comp_Normals(m_Mesh);
// MeshCore::MeshPointIterator p_it(m_Mesh);
// int i = 0;
//
// for(p_it.Begin(); p_it.More(); p_it.Next()){
// normals[i].Scale(m_CurvMax[i], m_CurvMax[i], m_CurvMax[i]);
// //p1.Set(PointArray[i].x, PointArray[i].y, PointArray[i].z);
// p2.Set(p_it->x + normals[i].x, p_it->y + normals[i].y, p_it->z + normals[i].z);
//
//
// if(m_CurvMax[i] < 100)
// log.addSingleLine(*p_it, p2, 1 ,0, 0, 0 );
//
// //cout << p_it->x << ", " << p_it->y << ", " << p_it->z << endl;
// //cout <<normals[i].x << ", " << normals[i].y << ", " << normals[i].z << endl;
// //cout << m_CurvMax[i] << endl;
// ++i;
//
// }
//
// log.saveToFile("c:/servolation.iv");
//}
// return true;
bool SpringbackCorrection::GetCurvature(TopoDS_Face aFace)
{
Base::Builder3D log;
Handle_Geom_Surface geom_surface;
geom_surface = BRep_Tool::Surface(aFace);
gp_Pnt proPnt;
double u_par,v_par,k1,k2;
gp_Vec D1U,D1V,D2U,D2V,D2UV;
Base::Vector3f p1,p2;
MeshCore::MeshPointArray PointArray = m_Mesh.GetPoints();
MeshCore::MeshFacetArray FacetArray = m_Mesh.GetFacets();
MeshCore::MeshPointIterator p_it(m_Mesh);
m_CurvMax.resize(PointArray.size());
for (unsigned int i=0; i<PointArray.size(); ++i)
{
proPnt.SetX(PointArray[i].x);
proPnt.SetY(PointArray[i].y);
proPnt.SetZ(PointArray[i].z);
GeomAPI_ProjectPointOnSurf aProjection(proPnt,geom_surface);
aProjection.LowerDistanceParameters(u_par,v_par);
// Berechne Krümmung
geom_surface->D2(u_par,v_par,proPnt,D1U,D1V,D2U,D2V,D2UV);
// erste & zweite Hauptkrümmung
k1 = D1U.CrossMagnitude(D2U) / D1U.Magnitude();
k2 = D1V.CrossMagnitude(D2V) / D1V.Magnitude();
/*if(k1>k2) PointArray[i].SetProperty(1/k1);
else PointArray[i].SetProperty(1/k2);*/
if (abs(k1)>abs(k2))
{
m_CurvMax[i] = 1/k1;
}
else
if (k2!=0)
m_CurvMax[i] = 1/k2;
else
m_CurvMax[i] = 100;
D1U.Cross(D1V);
D1U.Normalize();
D1U.Scale(m_CurvMax[i]);
p1.x = (float) (proPnt.X() + D1U.X());
p1.y = (float) (proPnt.Y() + D1U.Y());
p1.z = (float) (proPnt.Z() + D1U.Z());
p2.x = (float) proPnt.X();
p2.y = (float) proPnt.Y();
p2.z = (float) proPnt.Z();
log.addSingleLine(p2, p1, 1 ,0, 0, 0 );
}
MeshCore::MeshPointIterator v_it(m_Mesh);
MeshCore::MeshRefPointToPoints vv_it(m_Mesh);
MeshCore::MeshPointArray::_TConstIterator v_beg = m_Mesh.GetPoints().begin();
std::set<unsigned long> PntNei;
std::set<unsigned long> PntNei2;
std::set<unsigned long> PntNei3;
std::set<unsigned long> PntNei4;
std::set<unsigned long>::iterator pnt_it1;
std::set<unsigned long>::iterator pnt_it2;
std::set<unsigned long>::iterator pnt_it3;
std::set<unsigned long>::iterator pnt_it4;
std::vector<unsigned long> nei;
double curv;
std::vector<double> CurvCop = m_CurvMax;
for (v_it.Begin(); v_it.More(); v_it.Next())
{
PntNei = vv_it[v_it.Position()];
curv = m_CurvMax[v_it.Position()];
for (pnt_it1 = PntNei.begin(); pnt_it1 !=PntNei.end(); ++pnt_it1)
{
if (m_CurvMax[v_beg[*pnt_it1]._ulProp] < curv)
curv = m_CurvMax[v_beg[*pnt_it1]._ulProp];
PntNei2 = vv_it[v_beg[*pnt_it1]._ulProp];
for (pnt_it2 = PntNei2.begin(); pnt_it2 !=PntNei2.end(); ++pnt_it2)
{
if (m_CurvMax[v_beg[*pnt_it2]._ulProp] < curv)
curv = m_CurvMax[v_beg[*pnt_it2]._ulProp];
PntNei3 = vv_it[v_beg[*pnt_it2]._ulProp];
for (pnt_it3 = PntNei3.begin(); pnt_it3 !=PntNei3.end(); ++pnt_it3)
{
if (m_CurvMax[v_beg[*pnt_it3]._ulProp] < curv)
curv = m_CurvMax[v_beg[*pnt_it3]._ulProp];
PntNei4 = vv_it[v_beg[*pnt_it3]._ulProp];
for (pnt_it4 = PntNei4.begin(); pnt_it4 !=PntNei4.end(); ++pnt_it4)
{
if (m_CurvMax[v_beg[*pnt_it4]._ulProp] < curv)
curv = m_CurvMax[v_beg[*pnt_it4]._ulProp];
}
}
}
}
CurvCop[v_it.Position()] = curv;
}
m_CurvMax = CurvCop;
return true;
}
// 1. Computes the curvature of the mesh at the verticies
// 2. Stores the minimum curvatures along the neighbours for all verticies in a vector
std::vector<double> SpringbackCorrection::MeshCurvature(const TopoDS_Face& aFace, const MeshCore::MeshKernel& mesh)
{
TopLoc_Location aLocation;
Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);
const TColgp_Array1OfPnt2d& aUVNodes = aTr->UVNodes();
int n = aUVNodes.Length();
BRepAdaptor_Surface aSurface(aFace);
gp_Pnt2d par;
gp_Pnt P;
gp_Vec D1U, D1V, D2U, D2V, D2UV, nor, xvv, xuv, xuu;
double H,K; // Gaußsche- und mittlere Krümmung
std::vector<double> aMaxCurve, aMinCurve;
std::vector<double> curv(2);
for (int i=0; i<n; ++i)
{
par = aUVNodes.Value(i+1);
aSurface.D2(par.X(),par.Y(),P,D1U,D1V,D2U,D2V,D2UV);
//berechne Hilfsnormale
nor = D1U;
nor.Cross(D1V);
nor.Normalize();
xvv = D2V;
xuv = D2UV;
xuu = D2U;
xvv.Multiply(D1U*D1U);
xuv.Multiply(2*(D1U*D1V));
xuu.Multiply(D1V*D1V);
H = ((xvv - xuv + xuu)*nor);
H /= 2*((D1U*D1U)*(D1V*D1V) - (D1U*D1V)*(D1U*D1V));
K = ((nor*D2U)*(nor*D2V) - (nor*D2UV)*(nor*D2UV))/((D1U*D1U)*(D1V*D1V) - (D1U*D1V)*(D1U*D1V));
aMaxCurve.push_back(-(H - sqrt(H*H - K)));
aMinCurve.push_back(-(H + sqrt(H*H - K)));
}
double maxCurv = 0.0;
double avgCurv = 0.0;
double tmp1 = 1e+10;
double tmp2 = -1e+10;
double mean_curvMax = 0.0, mean_curvMin = 0.0;
int c1 = 0, c2 = 0;
m_CurvPos.clear();
m_CurvNeg.clear();
m_CurvMax.clear();
m_CurvPos.resize(mesh.CountPoints());
m_CurvNeg.resize(mesh.CountPoints());
m_CurvMax.resize(mesh.CountPoints());
for ( unsigned long i=0; i<n; i++ )
{
if (aMaxCurve[i] > 0) m_CurvPos[i] = 1 / aMaxCurve[i];
else m_CurvPos[i] = 1e+10;
if (aMinCurve[i] < 0) m_CurvNeg[i] = 1 / aMinCurve[i];
else m_CurvNeg[i] = -1e+10;
if (m_CurvPos[i] < tmp1)
tmp1 = m_CurvPos[i];
if (m_CurvNeg[i] > tmp2)
tmp2 = m_CurvNeg[i];
if (aMaxCurve[i] > 0)
{
++c1;
mean_curvMax += 1/aMaxCurve[i];
}
if (aMinCurve[i] < 0)
{
++c2;
mean_curvMin += 1/aMinCurve[i];
}
}
if (c1==0)
mean_curvMax = 1e+3;
else
mean_curvMax /= mesh.CountPoints();
if (c2==0)
mean_curvMin = -1e+3;
else
mean_curvMin /= mesh.CountPoints();
curv[0] = tmp1;
curv[1] = tmp2;
//Krümmung auf Netzbasis
for(int i=0; i<n; ++i)
{
// get all points
//MeshCore::MeshKernel& rMesh = mesh;
std::vector< Wm4::Vector3<float> > aPnts;
std::vector<Base::Vector3f> aPnts_tmp;
MeshCore::MeshPointIterator cPIt( mesh );
for ( cPIt.Init(); cPIt.More(); cPIt.Next() )
{
Wm4::Vector3<float> cP( cPIt->x, cPIt->y, cPIt->z );
Base::Vector3f cP_tmp( cPIt->x, cPIt->y, cPIt->z );
aPnts.push_back( cP );
aPnts_tmp.push_back(cP_tmp);
}
// get all point connections
std::vector<int> anIdx;
const std::vector<MeshCore::MeshFacet>& MeshFacetArray = mesh.GetFacets();
for ( std::vector<MeshCore::MeshFacet>::const_iterator jt = MeshFacetArray.begin(); jt != MeshFacetArray.end(); ++jt )
{
for (int i=0; i<3; i++)
{
anIdx.push_back( (int)jt->_aulPoints[i] );
}
}
// compute vertex based curvatures
Wm4::MeshCurvature<float> meshCurv(mesh.CountPoints(), &(aPnts[0]), mesh.CountFacets(), &(anIdx[0]));
// get curvature information now
const Wm4::Vector3<float>* aMaxCurvDir = meshCurv.GetMaxDirections();
const Wm4::Vector3<float>* aMinCurvDir = meshCurv.GetMinDirections();
const float* aMaxCurv = meshCurv.GetMaxCurvatures();
const float* aMinCurv = meshCurv.GetMinCurvatures();
double maxCurv = 0.0;
double avgCurv = 0.0;
double tmp1 = 1e+10;
double tmp2 = -1e+10;
double mean_curvMax = 0.0, mean_curvMin = 0.0;
int c1 = 0, c2 = 0;
m_CurvPos.clear();
m_CurvNeg.clear();
m_CurvMax.clear();
m_CurvPos.resize(mesh.CountPoints());
m_CurvNeg.resize(mesh.CountPoints());
m_CurvMax.resize(mesh.CountPoints());
for ( unsigned long i=0; i<mesh.CountPoints(); i++ )
{
if (aMaxCurv[i] > 0) m_CurvPos[i] = 1 / aMaxCurv[i];
else m_CurvPos[i] = 1e+10;
if (aMinCurv[i] < 0) m_CurvNeg[i] = 1 / aMinCurv[i];
else m_CurvNeg[i] = -1e+10;
if (m_CurvPos[i] < tmp1)
tmp1 = m_CurvPos[i];
if (m_CurvNeg[i] > tmp2)
tmp2 = m_CurvNeg[i];
if (aMaxCurv[i] > 0)
{
++c1;
mean_curvMax += 1/aMaxCurv[i];
}
if (aMinCurv[i] < 0)
{
++c2;
mean_curvMin += 1/aMinCurv[i];
}
}
if (c1==0)
mean_curvMax = 1e+3;
else
mean_curvMax /= mesh.CountPoints();
if (c2==0)
mean_curvMin = -1e+3;
else
mean_curvMin /= mesh.CountPoints();
curv[0] = tmp1;
curv[1] = tmp2;
}
return curv;
}
/*
bool SpringbackCorrection::MirrorMesh(std::vector<double> error)
{
// Flags: 0 - not yet checked
// 1 - no correction applied, but necessary
// 2 - first correction applied and still necessary
// 3 - done successfully
// 4 - done without success
// 5 - boundary point
int n = error.size();
m_error = error;
std::vector<int> InterPnts;
std::vector<unsigned long> InterFace;
std::vector<unsigned long> IFCopy;
bool boo = true;
std::vector<unsigned long> ind;
std::vector<unsigned long> copy;
MeshRef = m_Mesh;
std::vector<Base::Vector3f> NormalsRef = m_normals;
std::vector<Base::Vector3f> NormalOrig = m_normals;
PointArray = MeshRef.GetPoints();
MeshCore::MeshPointArray PntArray = m_Mesh.GetPoints();
MeshCore::MeshFacetArray FctArray = m_Mesh.GetFacets();
MeshCore::MeshFacetArray FacetArray = MeshRef.GetFacets();
MeshCore::MeshFacetIterator f_it(MeshRef);
MeshCore::MeshPointIterator v_it(MeshRef);
MeshCore::MeshRefPointToPoints vv_it(MeshRef);
MeshCore::MeshRefPointToFacets vf_it(MeshRef);
std::set<MeshCore::MeshPointArray::_TConstIterator> PntNei;
std::set<MeshCore::MeshFacetArray::_TConstIterator> FacetNei;
// Iterates in facets in form of MeshGeomFacets
std::set<MeshCore::MeshFacetArray::_TConstIterator>::iterator face_it;
std::set<MeshCore::MeshPointArray::_TConstIterator>::iterator pnt_it;
std::vector<Base::Vector3f> NeiLoc;
std::vector<Base::Vector3f> NorLoc;
std::vector<Base::Vector3f> TmpPntVec;
std::vector<unsigned long> TmpIndVec;
std::vector<unsigned long> nei;
bool k=true;
int count = 0;
while (k==true)
{
// ------ Self-Intersection Check + Correction ------------------------------------------------------
if (count ==2) break;
count++;
Base::Builder3D log3d;
Base::Builder3D loga;
Base::Vector3f Pnt, NeiPnt, NeiPntNext, NeiPntPrev, TmpPnt, TmpNor;
std::vector<Base::Vector3f> Neis;
double minScale, tmp;
bool sign;
ublas::matrix<double> A(3, 3);
ublas::matrix<double> b(1, 3);
ind.clear();
for (unsigned int i=0; i<m_Mesh.CountPoints(); ++i)
ind.push_back(i);
// do correction for selected points ---------------------------------
for (unsigned int j=0; j<ind.size(); ++j)
{
sign = (error[ind[j]] > 0); // (+) -> true , (-) -> false
MeshRef.Assign(PointArray, FacetArray);
v_it.Set(ind[j]);
Pnt = *v_it;
PntNei = vv_it[ind[j]];
FacetNei = vf_it[ind[j]];
nei.clear();
// falls boundary-point tue nichts bzw. gehe zum nächsten punkt
if (FacetNei.size() != PntNei.size())
{
PointArray[ind[j]]._ucFlag = 5;
m_CurvMax[ind[j]] = abs(error[ind[j]]); // vorübergehend
continue;
}
// ordne nachbarn
ReorderNeighbourList(PntNei,FacetNei,nei,ind[j]);
NeiLoc.clear();
NorLoc.clear();
NeiLoc.push_back(Pnt);
NorLoc.push_back(NormalsRef[ind[j]]);
for (unsigned int r=0; r<nei.size(); ++r)
{
v_it.Set(nei[r]);
NeiLoc.push_back(*v_it);
NorLoc.push_back(NormalsRef[nei[r]]);
}
if (count == 2)
{
if (sign ==true) minScale = -(1e+10);
else minScale = 1e+10;
minScale = LocalCorrection(NeiLoc,NorLoc,sign,minScale);
if ((abs(0.8*minScale) - abs(error[ind[j]])) > 0)
{
PointArray[ind[j]]._ucFlag = 3;
m_CurvMax[ind[j]] = abs(minScale);
//cout << "t, ";
continue;
}
else
{
PointArray[ind[j]]._ucFlag = 4;
m_CurvMax[ind[j]] = abs(minScale);
cout << "f, ";
continue;
}
}
if (sign ==true) minScale = -(1e+10);
else minScale = 1e+10;
minScale = LocalCorrection(NeiLoc,NorLoc,sign,minScale);
if ((abs(0.8*minScale) - abs(error[ind[j]])) > 0)
{
PointArray[ind[j]]._ucFlag = 3;
m_CurvMax[ind[j]] = abs(minScale);
continue;
}
//---------------------------- 1. Korrektur -------------------------
tmp = 0;
std::vector<Base::Vector3f> ConvComb = FillConvex(NeiLoc,NorLoc,20);
for (unsigned int l=0; l<ConvComb.size(); ++l)
{
if (sign ==true) minScale = -(1e+10);
else minScale = 1e+10;
NeiLoc[0] = ConvComb[l];
minScale = LocalCorrection(NeiLoc,NorLoc,sign,minScale);
if (abs(minScale) > abs(tmp))
{
tmp = minScale;
TmpPnt = NeiLoc[0];
}
}
NeiLoc[0] = PointArray[ind[j]];
cout << "new minScale: " << tmp << endl;
if ((abs(0.8*tmp) - abs(error[ind[j]])) > 0)
{
PointArray[ind[j]].Set(TmpPnt.x, TmpPnt.y, TmpPnt.z);
PointArray[ind[j]]._ucFlag = 3;
m_CurvMax[ind[j]] = abs(tmp);
continue;
}
else
{
PointArray[ind[j]]._ucFlag = 2;
m_CurvMax[ind[j]] = abs(tmp);
}
//------------------------------- END -------------------------------
// update
for (unsigned int r=0; r<nei.size(); ++r)
{
v_it.Set(nei[r]);
NeiLoc[r+1] = *v_it;
}
MeshRef.Assign(PointArray, FacetArray);
//---------------------------- 2. Korrektur -------------------------
tmp = GlobalCorrection(NeiLoc,NorLoc,sign,ind[j]);
//MeshRef.Assign(PointArray, FacetArray);
//m_Mesh = MeshRef;
//return true;
cout << "2: " << tmp << endl;
if ((abs(0.8*tmp) - abs(error[ind[j]])) > 0)
{
PointArray[ind[j]].Set(NeiLoc[0].x, NeiLoc[0].y, NeiLoc[0].z);
NormalsRef[ind[j]].Set(NorLoc[0].x, NorLoc[0].y, NorLoc[0].z);
PointArray[ind[j]]._ucFlag = 3;
m_CurvMax[ind[j]] = abs(tmp);
continue;
}
else
{
if (m_CurvMax[ind[j]] < abs(tmp))
{
m_CurvMax[ind[j]] = abs(tmp);
PointArray[ind[j]].Set(NeiLoc[0].x, NeiLoc[0].y, NeiLoc[0].z);
NormalsRef[ind[j]].Set(NorLoc[0].x, NorLoc[0].y, NorLoc[0].z);
}
// flag bleibt 2
}
//------------------------------- END -------------------------------
} // end for
cout << "Replace Mesh..." << endl;
PntArray = PointArray;
m_normals = NormalsRef;
m_Mesh = MeshRef;
} // end while
double ver, mx=100;
for (unsigned int i=0; i<error.size(); ++i)
{
ver = m_CurvMax[i] / abs(error[i]);
if (ver < mx)
mx = ver;
}
//cout << "skalierung: " << mx << endl;
//for(int i=0; i<error.size(); ++i)
//error[i] *= mx;
// deform CAD-Mesh with regard to the scaled normals
MeshCore::MeshPointIterator p_it(m_Mesh);
Base::Builder3D log,log2;
std::vector<int> IndexVec,NumVec, NumVecCopy;
int c, lastNum, lastInd;
// kritische punkte plus anzahl seiner kritischen nachbarn speichern
//ind.clear();
for (unsigned int j=0; j<ind.size(); ++j)
{
if (PointArray[ind[j]]._ucFlag == 3 || PointArray[ind[j]]._ucFlag == 5)
{
//ind.push_back(ind[j]);
continue;
}
else
{
c=0;
PntNei = vv_it[ind[j]];
for (pnt_it = PntNei.begin(); pnt_it != PntNei.end(); ++pnt_it)
{
if (PointArray[(*pnt_it)->_ulProp]._ucFlag == 4)
c++;
}
IndexVec.push_back(ind[j]);
NumVec.push_back(c);
}
}
// normalenskalierung
for (unsigned int j=0; j<ind.size(); ++j)
{
if ( ( abs(0.8*m_CurvMax[ind[j]]) - abs(error[ind[j]]) ) < 0)
{
if (error[ind[j]] < 0)
m_normals[ind[j]].Scale((float) (0.8*m_CurvMax[ind[j]]),(float) (0.8*m_CurvMax[ind[j]]),(float) (0.8*m_CurvMax[ind[j]]));
else
m_normals[ind[j]].Scale((float) (-0.8*m_CurvMax[ind[j]]),(float) (-0.8*m_CurvMax[ind[j]]), (float) (-0.8*m_CurvMax[ind[j]]));
}
else
m_normals[ind[j]].Scale((float) -error[ind[j]],(float) -error[ind[j]],(float) -error[ind[j]]);
}
for (unsigned int j=0; j<ind.size(); ++j)
{
log.addSingleLine(PointArray[ind[j]],PointArray[ind[j]] + m_normals[ind[j]],2,1,1,1); // white arrows
PntArray[ind[j]].Set(PntArray[ind[j]].x + m_normals[ind[j]].x,
PntArray[ind[j]].y + m_normals[ind[j]].y,
PntArray[ind[j]].z + m_normals[ind[j]].z);
}
m_Mesh.Assign(PntArray, FctArray);
MeshRef = m_Mesh;
log.saveToFile("c:/deformation.iv");
// kritische punkte nach der anzahl seiner kritischen nachbarn sortieren
NumVecCopy = NumVec;
std::vector<int> SortNumVec(NumVec.size(), -1);
std::vector<int> SortIndVec(NumVec.size(), -1);
cout << NumVec.size() << endl;
//cout << "vor dem sortieren: ";
//for(int j=0; j<NumVec.size(); ++j)
//{
//cout << NumVec[j] << ", ";
//}
//cout << endl;
for (unsigned int j=0; j<NumVecCopy.size(); ++j)
{
lastNum = NumVec.back();
lastInd = IndexVec.back();
NumVec.pop_back();
IndexVec.pop_back();
c=0;
for (unsigned int i=0; i<NumVecCopy.size(); ++i)
{
if (NumVecCopy[i] < lastNum)
++c;
}
while (SortNumVec[c] == lastNum)
++c;
SortNumVec[c] = lastNum;
SortIndVec[c] = lastInd;
}
//cout << "danach: ";
//for(int j=0; j<SortNumVec.size(); ++j)
//{
//cout << SortNumVec[j] << ", ";
//}
//cout << endl;
NeiLoc.clear();
NorLoc.clear();
Base::Builder3D log1;
MeshCore::MeshKernel mesh;
MeshCore::MeshPoint mpnt;
MeshCore::MeshPointArray mPointArray;
MeshCore::MeshFacetArray mFacetArray;
float w;
for (unsigned int j=0; j<SortIndVec.size(); ++j)
{
Base::Vector3f bvec(0.0, 0.0, 0.0);
NeiLoc.clear();
NeiLoc.push_back(bvec);
PntNei = vv_it[SortIndVec[j]];
FacetNei = vf_it[SortIndVec[j]];
nei.clear();
// ordne nachbarn
ReorderNeighbourList(PntNei,FacetNei,nei,SortIndVec[j]);
mPointArray.clear();
for (unsigned int i=0; i<nei.size(); ++i)
{
mpnt = PntArray[nei[i]];
mPointArray.push_back(mpnt);
//!!!!!!!!!!!!!!!!! NeiLoc.size() must be greater than 3!!!!!!!!!!!!!!!
if (PntArray[nei[i]]._ucFlag != 4)
{
NeiLoc.push_back(PntArray[nei[i]]);
log1.addSinglePoint(PntArray[nei[i]].x, PntArray[nei[i]].y, PntArray[nei[i]].z, 2,1,1,1);
mPointArray.push_back(mpnt);
}
else
{
bvec += PntArray[nei[i]];
log1.addSinglePoint(PntArray[nei[i]].x, PntArray[nei[i]].y, PntArray[nei[i]].z, 2,1,0,0);
}
}
log1.saveToFile("c:/nachbarn.iv");
mesh.Assign(mPointArray, mFacetArray);
// need at least one facet to perform the PCA
MeshCore::MeshGeomFacet face;
mesh.AddFacet(face);
// berechne hauptachsen
MeshCore::MeshEigensystem pca(mesh);
pca.Evaluate();
Base::Matrix4D T1 = pca.Transform();
std::vector<Base::Vector3f> v(3);
v[0].x = (float) T1[0][0];
v[0].y = (float) T1[0][1];
v[0].z = (float) T1[0][2];
v[1].x = (float) T1[1][0];
v[1].y = (float) T1[1][1];
v[1].z = (float) T1[1][2];
v[2].x = (float) T1[2][0];
v[2].y = (float) T1[2][1];
v[2].z = (float) T1[2][2];
v[0].Normalize();
v[1].Normalize();
v[2].Normalize();
double deg,temp=0;
int s;
for (int i=0; i<3; ++i)
{
deg = v[i]*NormalOrig[SortIndVec[j]];
if (abs(deg)>temp)
{
temp = abs(deg);
s=i;
}
}
if (v[s].z < 0.0)
v[s] *= -1;
for (unsigned int i=0; i<NeiLoc.size(); ++i)
NorLoc.push_back(v[s]);
// gewichtung (im verhältnis 1:2)
w = float(1.0) /(float(NeiLoc.size()) + float(PntNei.size()) - float(1.0));
bvec.Scale(w,w,w);
for (unsigned int i=1; i<NeiLoc.size(); ++i)
{
bvec.x = bvec.x + 2*w*NeiLoc[i].x;
bvec.y = bvec.y + 2*w*NeiLoc[i].y;
bvec.z = bvec.z + 2*w*NeiLoc[i].z;
}
NeiLoc[0] = bvec;
log1.addSinglePoint(NeiLoc[0],2,0,1,0);
std::vector<Base::Vector3f> Convs = FillConvex(NeiLoc, NorLoc, 20);
for (unsigned int i=0; i<Convs.size(); ++i)
log1.addSinglePoint(Convs[i],2,0,0,0);
log1.saveToFile("c:/nachbarn.iv");
PntArray[SortIndVec[j]].Set(Convs[0].x, Convs[0].y, Convs[0].z);
PntArray[SortIndVec[j]]._ucFlag = 3;
}
m_Mesh.Assign(PntArray, FctArray);
return true;
for (p_it.Begin(); p_it.More(); p_it.Next())
{
if (PointArray[p_it.Position()]._ucFlag == 3)
{
log.addSingleLine(*p_it,*p_it + m_normals[p_it.Position()],2,1,1,1); // red arrows
PntArray[p_it.Position()].Set(PntArray[p_it.Position()].x + m_normals[p_it.Position()].x,
PntArray[p_it.Position()].y + m_normals[p_it.Position()].y,
PntArray[p_it.Position()].z + m_normals[p_it.Position()].z);
}
if (PointArray[p_it.Position()]._ucFlag == 4)
{
log.addSingleLine(*p_it,*p_it + m_normals[p_it.Position()],2,1,0,0); // red arrows
PntArray[p_it.Position()].Set(PntArray[p_it.Position()].x + m_normals[p_it.Position()].x,
PntArray[p_it.Position()].y + m_normals[p_it.Position()].y,
PntArray[p_it.Position()].z + m_normals[p_it.Position()].z);
}
}
m_Mesh.Assign(PntArray, FctArray);
log.saveToFile("c:/deformation.iv");
return true;
}
*/
/*
double SpringbackCorrection::LocalCorrection(std::vector<Base::Vector3f> Neib ,
std::vector<Base::Vector3f> Normal, bool sign, double minScale)
{
Base::Vector3f Pnt, NeiPnt, NeiPntNext, NeiPntPrev;
ublas::matrix<double> A(3, 3);
ublas::matrix<double> b(1, 3);
// 2. Spalte bleibt unverändert
A(0,2) = -Normal[0].x;
A(1,2) = -Normal[0].y;
A(2,2) = -Normal[0].z;
// forward
for (unsigned int k=1; k<Neib.size(); ++k)
{
NeiPnt = Neib[k];
if ((k+1) == Neib.size())
{
NeiPntNext = Neib[1];
}
else
{
NeiPntNext = Neib[k+1];
}
A(0,2) = -Normal[0].x;
A(0,0) = Normal[k].x;
A(0,1) = (NeiPntNext.x - NeiPnt.x);
A(1,2) = -Normal[0].y;
A(1,0) = Normal[k].y;
A(1,1) = (NeiPntNext.y - NeiPnt.y);
A(2,2) = -Normal[0].z;
A(2,0) = Normal[k].z;
A(2,1) = (NeiPntNext.z - NeiPnt.z);
b(0,0) = Neib[0].x - NeiPnt.x;
b(0,1) = Neib[0].y - NeiPnt.y;
b(0,2) = Neib[0].z - NeiPnt.z;
//cout << "A-Matrix: " << endl;
//cout << A(0,0) << ", " << A(0,1) << ", " << A(0,2) << endl;
//cout << A(1,0) << ", " << A(1,1) << ", " << A(1,2) << endl;
//cout << A(2,0) << ", " << A(2,1) << ", " << A(2,2) << endl;
//cout << endl;
//cout << "b-Vector: " << endl;
//cout << b(0,0) << ", " << b(0,1) << ", " << b(0,2) << endl;
//cout << endl;
atlas::gesv(A,b);
//cout << "solution: " << endl;
//cout << b(0,0) << ", " << b(0,1) << ", " << b(0,2) << endl;
//cout << endl;
if ((b(0,2)<=0) && (sign == true) && (b(0,1)>=0) && (b(0,1)<=1))
{
if (minScale < b(0,2))
minScale = b(0,2);
}
else if (b(0,2)>=0 && sign == false && (b(0,1)>=0) && (b(0,1)<=1))
{
if (minScale > b(0,2))
minScale = b(0,2);
}
}
// backward
for (unsigned int k=1; k<Neib.size(); ++k)
{
NeiPnt = Neib[k];
if (k == 1)
{
NeiPntPrev = Neib[Neib.size()-1];
}
else
{
NeiPntPrev = Neib[k-1];
}
A(0,2) = -Normal[0].x;
A(0,0) = Normal[k].x;
A(0,1) = (NeiPntPrev.x - NeiPnt.x);
A(1,2) = -Normal[0].y;
A(1,0) = Normal[k].y;
A(1,1) = (NeiPntPrev.y - NeiPnt.y);
A(2,2) = -Normal[0].z;
A(2,0) = Normal[k].z;
A(2,1) = (NeiPntPrev.z - NeiPnt.z);
b(0,0) = Neib[0].x - NeiPnt.x;
b(0,1) = Neib[0].y - NeiPnt.y;
b(0,2) = Neib[0].z - NeiPnt.z;
//cout << "A-Matrix: " << endl;
//cout << A(0,0) << ", " << A(0,1) << ", " << A(0,2) << endl;
//cout << A(1,0) << ", " << A(1,1) << ", " << A(1,2) << endl;
//cout << A(2,0) << ", " << A(2,1) << ", " << A(2,2) << endl;
//cout << endl;
//cout << "b-Vector: " << endl;
//cout << b(0,0) << ", " << b(0,1) << ", " << b(0,2) << endl;
//cout << endl;
atlas::gesv(A,b);
//cout << "solution: " << endl;
//cout << b(0,0) << ", " << b(0,1) << ", " << b(0,2) << endl;
//cout << endl;
if (b(0,2)<0 && sign == true && (b(0,1)>=0) && (b(0,1)<=1))
{
if (minScale < b(0,2))
minScale = b(0,2);
}
else if (b(0,2)>0 && sign == false && (b(0,1)>=0) && (b(0,1)<=1))
{
if (minScale > b(0,2))
minScale = b(0,2);
}
}
return minScale;
}
*/
/*
std::vector<Base::Vector3f> SpringbackCorrection::FillConvex(std::vector<Base::Vector3f> Neib, std::vector<Base::Vector3f> Normals, int n)
{
std::vector<Base::Vector3f> ConvComb;
Base::Vector3f tmp;
for (unsigned int i=1; i<Neib.size(); ++i)
{
for (int j=0; j<n; ++j)
{
//cout << "t, " ;
tmp = Neib[i] - Neib[0];
tmp.Scale(float(j)/float(n), float(j)/float(n), float(j)/float(n));
if (InsideCheck(Neib[0] + tmp, Normals[0], Neib) == true)
ConvComb.push_back(Neib[0] + tmp);
else;
//cout << "f, " ;
}
}
cout << endl;
return ConvComb;
}
*/
/*
bool SpringbackCorrection::InsideCheck(Base::Vector3f pnt, Base::Vector3f normal, std::vector<Base::Vector3f> Neib)
{
Base::Vector3f Pnt, NeiPnt, NeiPntNext, Cross;
ublas::matrix<double> A(3, 3);
ublas::matrix<double> b(1, 3);
bool b1 = true, b2;
for (unsigned int k=1; k<Neib.size(); ++k)
{
NeiPnt = Neib[k];
if ((k+1) == Neib.size())
{
NeiPntNext = Neib[1];
}
else
{
NeiPntNext = Neib[k+1];
}
Cross = normal%(NeiPntNext - NeiPnt);
A(0,0) = normal.x;
A(0,1) = (NeiPntNext.x - NeiPnt.x);
A(0,2) = -Cross.x;
A(1,0) = normal.y;
A(1,1) = (NeiPntNext.y - NeiPnt.y);
A(1,2) = -Cross.y;
A(2,0) = normal.z;
A(2,1) = (NeiPntNext.z - NeiPnt.z);
A(2,2) = -Cross.z;
b(0,0) = pnt.x - NeiPnt.x;
b(0,1) = pnt.y - NeiPnt.y;
b(0,2) = pnt.z - NeiPnt.z;
atlas::gesv(A,b);
if (b1==true)
{
if ( b(0,2) < 0)
{
b1 = false;
b2 = true;
}
else if (b(0,2)>0)
{
b1 = false;
b2 = false;
}
}
if (b1==false)
{
if ((b2 == true) && (b(0,2) > 0)) return false;
if ((b2 == false) && (b(0,2) < 0)) return false;
}
}
return true;
}
*/
/*
double SpringbackCorrection::GlobalCorrection(std::vector<Base::Vector3f> NeiLoc, std::vector<Base::Vector3f> NorLoc,
bool sign, int ind)
{
double minScale,mScRef,tmp = 0;
Base::Vector3f TmpPnt, TmpNor;
if (sign ==true) mScRef = -(1e+10);
else mScRef = 1e+10;
minScale = mScRef;
minScale = LocalCorrection(NeiLoc,NorLoc,sign,minScale);
if ((abs(0.8*minScale) - abs(m_error[ind])) > 0)
{
PointArray[ind]._ucFlag = 3;
m_CurvMax[ind] = abs(minScale);
return minScale;
}
std::vector<Base::Vector3f> ConvComb = FillConvex(NeiLoc,NorLoc,20);
// füge schwerpunkte der umgebenden faces hinzu
std::set<MeshCore::MeshFacetArray::_TConstIterator> FacetNei;
std::set<MeshCore::MeshFacetArray::_TConstIterator>::iterator face_it;
MeshCore::MeshFacetIterator f_it (MeshRef);
MeshCore::MeshRefPointToFacets vf_it(MeshRef);
FacetNei = vf_it[ind];
for (face_it = FacetNei.begin(); face_it != FacetNei.end(); ++face_it)
{
TmpPnt.Set(0.0, 0.0, 0.0);
TmpPnt += PointArray[(*face_it)->_aulPoints[0]];
TmpPnt += PointArray[(*face_it)->_aulPoints[1]];
TmpPnt += PointArray[(*face_it)->_aulPoints[2]];
TmpPnt.Scale((float) (1.0/3.0),(float) (1.0/3.0),(float) (1.0/3.0));
ConvComb.push_back(TmpPnt);
}
//Base::Builder3D logg;
//for(int i=0; i<NeiLoc.size(); ++i)
// logg.addSinglePoint(NeiLoc[i], 2,1,0,0);
//for(int i=0; i<ConvComb.size(); ++i)
// logg.addSinglePoint(ConvComb[i]);
//logg.saveToFile("c:/convex.iv");
for (unsigned int i=0; i<ConvComb.size(); ++i)
{
for (unsigned int j=1; j<NorLoc.size()-1; ++j)
{
minScale = mScRef;
NeiLoc[0] = ConvComb[i];
NorLoc[0] = NorLoc[j];
minScale = LocalCorrection(NeiLoc,NorLoc,sign,minScale);
if (minScale > tmp)
{
tmp = minScale;
TmpPnt = NeiLoc[0];
TmpNor = NorLoc[0];
}
}
}
NeiLoc[0] = TmpPnt;
NorLoc[0] = TmpNor;
if ((abs(0.8*tmp) - abs(m_error[ind])) > 0)
{
PointArray[ind]._ucFlag = 3;
m_CurvMax[ind] = abs(tmp);
}
else
{
PointArray[ind]._ucFlag = 4;
m_CurvMax[ind] = abs(tmp);
}
return tmp;
}
/*
/*! \brief Reorder the neighbour list
This function will reorder the list in one-direction. Clockwise or counter clockwise is depending on the
facet list and will not be checked by this function. (i.e the third vertex i.e vertex in first facet that
is not the CurIndex or the first neighbour in pnt[Ok, I am also lost with this..., just debug and step to see what I mean...])
*/
/*
void SpringbackCorrection::ReorderNeighbourList(std::set<MeshCore::MeshPointArray::_TConstIterator> &pnt,
std::set<MeshCore::MeshFacetArray::_TConstIterator> &face, std::vector<unsigned long> &nei, unsigned long CurInd)
{
std::set<MeshCore::MeshPointArray::_TConstIterator>::iterator pnt_it;
std::set<MeshCore::MeshFacetArray::_TConstIterator>::iterator face_it;
std::vector<unsigned long>::iterator vec_it;
std::vector<unsigned long>::iterator ulong_it;
unsigned long PrevIndex;
if (face.size() != pnt.size()) //this means boundary point
{
for (pnt_it = pnt.begin(); pnt_it != pnt.end(); ++pnt_it)
{
int c = 0;
for (face_it = face.begin(); face_it != face.end(); ++face_it)
{
if ((*pnt_it)[0]._ulProp == (*face_it)[0]._aulPoints[0])
++c;
if ((*pnt_it)[0]._ulProp == (*face_it)[0]._aulPoints[1])
++c;
if ((*pnt_it)[0]._ulProp == (*face_it)[0]._aulPoints[2])
++c;
}
if (c==1)
break;
}
}
else
pnt_it = pnt.begin();
face_it = face.begin();
nei.push_back((*pnt_it)->_ulProp); //push back first neighbour
vec_it = nei.begin();
PrevIndex = nei[0]; //Initialize PrevIndex
for (unsigned int i = 1; i < pnt.size(); i++) //Start
{
while (true)
{
std::vector<unsigned long> facetpnt;
facetpnt.push_back((*face_it)->_aulPoints[0]); //push back into a vector for easier iteration
facetpnt.push_back((*face_it)->_aulPoints[1]);
facetpnt.push_back((*face_it)->_aulPoints[2]);
if ((ulong_it = find(facetpnt.begin(), facetpnt.end(), PrevIndex)) == facetpnt.end()) //if PrevIndex not found
{
//in current facet
if (face_it != face.end())
++face_it; //next face please
else
break;
continue;
}
else
{
for (unsigned int k = 0 ; k < 3; k++)
{
//If current facetpnt[k] is not yet in nei_list AND it is not the CurIndex
if (((vec_it = find(nei.begin(), nei.end(), facetpnt[k])) == nei.end()) && facetpnt[k] != CurInd)
{
face.erase(face_it); //erase this face
nei.push_back(facetpnt[k]); //push back the index
PrevIndex = facetpnt[k]; //this index is now PrevIndex
face_it = face.begin(); //reassign the iterator
break; //end this for-loop
}
}
break; //end this while loop
}
}
}
}
*/
bool SpringbackCorrection::Visit(const MeshCore::MeshFacet &rclFacet, const MeshCore::MeshFacet &rclFrom, unsigned long ulFInd, unsigned long ulLevel)
{
if (ulLevel != m_RingCurrent)
{
++m_RingCurrent;
if (m_RingVector.size() == 0)
{
return false;
}
//else if(m_RingVector.size() < 2 && m_RingCurrent > 2)
//{
// m_RingVector.clear();
// return false;
//}
else
{
m_RegionVector.push_back(m_RingVector);
m_RingVector.clear();
}
}
if (rclFacet._ulProp == 1 && rclFrom._ulProp == 1)
m_RingVector.push_back(ulFInd);
return true;
}