Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
#include "IsoLayerGeneration.h"
#include <fstream>
void IsoLayerGeneration::generateIsoSurface(PolygenMesh* isoSurface, int _layerNum, bool fixedIndex, double indexVal) {
double isoCurveValue = 0.0;
double layer_space = _layerNum;
//if (max_distance > 1) max_distance = 1;
int layerNum = (int)((max_distance - min_distance) / layer_space);
std::cout << min_SingularDistance << "*________________* " << max_SingularDistance << std::endl;
isInSingularZone = false;
/**************Remove these****************/
// layerNum = 30; //Remember to remove this
//layer_space = 2;
/*****************************************/
std::cout << "max_distance: " << max_distance << std::endl;
std::cout << "min_distance: " << min_distance << std::endl;
//std::cout << "layer Num: " << layerNum << std::endl;
double first_distance = 5.00;
isoCurveValue = min_distance + 0.2 - layer_space;
double maxBoundScalar = -9e10;
for (GLKPOSITION nodePos = tetMesh->GetNodeList().GetHeadPosition(); nodePos;) {
QMeshNode* meshNode = (QMeshNode*)tetMesh->GetNodeList().GetNext(nodePos);
if (meshNode->isInteriorBoundary) {
if (maxBoundScalar < meshNode->scalarField) {
maxBoundScalar = meshNode->scalarField;
}
}
}
int i = 0;
if (fixedIndex) {
QMeshPatch* layer;
std::cout << "IndexVal\t" << indexVal << std::endl;
layer = generatesingleIsoSurface(indexVal, isoSurface);
if (layer->GetNodeNumber() == 0) {
std::cout << "this layer have no node!" << std::endl;
}
else {
layer->SetIndexNo(isoSurface->GetMeshList().GetCount());
isoSurface->meshList.AddTail(layer);
std::cout << layer->GetIndexNo() << " Layer, isoValue = " << isoCurveValue << ", nodeNum = " << layer->GetNodeNumber() << std::endl;
}
}
else {
while (isoCurveValue <= max_distance) {
//std::cout << "i: " << i << std::endl;
/*if(i>20)
isoCurveValue = isoCurveValue + 2 * layer_space;*/
if (true)
isoCurveValue = isoCurveValue + layer_space;
else
isoCurveValue = isoCurveValue + 1;
/*if (i>2)
isoCurveValue = isoCurveValue + 1.5 * layer_space;
else
isoCurveValue = isoCurveValue + 1;*/
if (isoCurveValue > max_distance) break;
i++;
QMeshPatch* layer;
if ((isoCurveValue >= min_SingularDistance) && (isoCurveValue <= max_SingularDistance)) {
isInSingularZone = true;
singularZoneIndex = isoCurveValue;
}
/*if (isoCurveValue > -0.6 && isoCurveValue < 0.6) {
layer = hullMesh->CopyMesh();
planeCutSurfaceMesh_delete(layer, 0, 1);
planeCutSurfaceMesh_delete(layer, 30, 2);
}
else*/ layer = generatesingleIsoSurface(isoCurveValue, isoSurface);
/*bool isValid = planeCutSurfaceMesh_delete(layer, 23, 3);
if (!isValid) continue;
else {
isValid = planeCutSurfaceMesh_delete(layer, 56, 0);
if (!isValid) continue;
else {
isValid = planeCutSurfaceMesh_delete(layer, 64, 1);
if (!isValid) continue;
else {
isValid = planeCutSurfaceMesh_delete(layer, 40.5, 2);
if (!isValid) continue;
else {
isValid = planeCutSurfaceMesh_delete(layer, 150, 4);
if (!isValid) continue;
}
}
}
}*/
if (layer->GetNodeNumber() == 0) {
std::cout << "this layer have no node!" << std::endl; continue;
}
//index begin from 0
layer->SetIndexNo(isoSurface->GetMeshList().GetCount());
isoSurface->meshList.AddTail(layer);
std::cout << layer->GetIndexNo() << " Layer, isoValue = " << isoCurveValue << ", nodeNum = " << layer->GetNodeNumber() << std::endl;
}
reoOrderLayers(isoSurface);
}
if (isInSingularZone) {
std::cout << " One layer in planar singularity prone area; Index = " << singularZoneIndex << std::endl;
}
//std::cout << "layer Num: " << layerNum << std::endl;
}
/*Main function for iso-surface substraction from tetrahedral model*/
QMeshPatch* IsoLayerGeneration::generatesingleIsoSurface(double isoValue, PolygenMesh* isoSurface)
{
QMeshPatch* layer = new QMeshPatch;
layer->isoSurfaceValue = isoValue;
//when the node iso-value is equal to surface value, add this eps.
double eps = 1.0e-5;
for (GLKPOSITION Pos = tetMesh->GetNodeList().GetHeadPosition(); Pos;) {
QMeshNode* Node = (QMeshNode*)tetMesh->GetNodeList().GetNext(Pos);
//if (Node->in_ConvexHull) continue;
if (abs(Node->scalarField - isoValue) < eps) {
if (Node->scalarField > isoValue) Node->scalarField = isoValue + eps;
else Node->scalarField = isoValue - eps;
}
}
// build node list for isoSurface, this comes from the edge list
for (GLKPOSITION Pos = tetMesh->GetEdgeList().GetHeadPosition(); Pos;) {
QMeshEdge* Edge = (QMeshEdge*)tetMesh->GetEdgeList().GetNext(Pos);
Edge->installedIsoNode = nullptr;
Edge->isLocateIsoNode = false;
if (Edge->in_convexHull) continue;
double a = Edge->GetStartPoint()->scalarField;
double b = Edge->GetEndPoint()->scalarField;
if ((isoValue - a) * (isoValue - b) < 0.0) {
double alpha = (isoValue - a) / (b - a);
double p1[3], p2[3], pp[3];
Edge->GetStartPoint()->GetCoord3D(p1[0], p1[1], p1[2]);
Edge->GetEndPoint()->GetCoord3D(p2[0], p2[1], p2[2]);
for (int j = 0; j < 3; j++)
pp[j] = (1.0 - alpha) * p1[j] + alpha * p2[j];
QMeshNode* isoNode = new QMeshNode;
isoNode->relatedTetEdge = Edge;
isoNode->SetMeshPatchPtr(layer);
isoNode->SetCoord3D(pp[0], pp[1], pp[2]);
isoNode->SetIndexNo(layer->GetNodeList().GetCount() + 1);
layer->GetNodeList().AddTail(isoNode);
Edge->installedIsoNode = isoNode;
Edge->isLocateIsoNode = true;
}
}
// build edge list for isoSurface, this comes from the face list
for (GLKPOSITION Pos = tetMesh->GetFaceList().GetHeadPosition(); Pos;) {
QMeshFace* Face = (QMeshFace*)tetMesh->GetFaceList().GetNext(Pos);
Face->installedIsoEdge = nullptr;
Face->isLocatedIsoEdge = false;
if(Face->in_convexHull) continue;
int positiveNum = 0;
for (int i = 0; i < 3; i++) {
if (Face->GetNodeRecordPtr(i)->scalarField > isoValue) positiveNum++;
}
if (positiveNum == 0 || positiveNum == 3) continue;
else if (positiveNum == 1) {
QMeshEdge* isoEdge = new QMeshEdge;
//detect which node is positive
QMeshNode* PostiveNode;
int index = 0;
for (index = 0; index < 3; index++) {
PostiveNode = Face->GetNodeRecordPtr(index);
if (PostiveNode->scalarField > isoValue) break;
}
QMeshEdge* Edge = Face->GetEdgeRecordPtr(index + 1);
if (Edge->in_convexHull) { std::cout << "Got the error!!!\n"; }
QMeshNode* startNode = Edge->installedIsoNode;
isoEdge->SetStartPoint(startNode);
Edge = Face->GetEdgeRecordPtr((index + 2) % 3 + 1);
if (Edge->in_convexHull) { std::cout << "Got the error!!!\n"; }
QMeshNode* endNode = Edge->installedIsoNode;
isoEdge->SetEndPoint(endNode);
isoEdge->SetMeshPatchPtr(layer);
isoEdge->SetIndexNo(layer->GetEdgeList().GetCount() + 1);
(startNode->GetEdgeList()).AddTail(isoEdge);
(endNode->GetEdgeList()).AddTail(isoEdge);
layer->GetEdgeList().AddTail(isoEdge);
Face->installedIsoEdge = isoEdge;
Face->isLocatedIsoEdge = true;
}
else if (positiveNum == 2) {
QMeshEdge* isoEdge = new QMeshEdge;
//detect which node is negative
QMeshNode* NegativeNode;
int index = 0;
for (index = 0; index < 3; index++) {
NegativeNode = Face->GetNodeRecordPtr(index);
if (NegativeNode->scalarField < isoValue) break;
}
QMeshEdge* Edge = Face->GetEdgeRecordPtr((index + 2) % 3 + 1);
QMeshNode* startNode = Edge->installedIsoNode;
isoEdge->SetStartPoint(startNode);
Edge = Face->GetEdgeRecordPtr(index + 1);
QMeshNode* endNode = Edge->installedIsoNode;
isoEdge->SetEndPoint(endNode);
isoEdge->SetMeshPatchPtr(layer);
isoEdge->SetIndexNo(layer->GetEdgeList().GetCount() + 1);
(startNode->GetEdgeList()).AddTail(isoEdge);
(endNode->GetEdgeList()).AddTail(isoEdge);
layer->GetEdgeList().AddTail(isoEdge);
Face->installedIsoEdge = isoEdge;
Face->isLocatedIsoEdge = true;
}
}
// build face list for isoSurface, this comes from the face list
for (GLKPOSITION Pos = tetMesh->GetTetraList().GetHeadPosition(); Pos;) {
QMeshTetra* Tetra = (QMeshTetra*)tetMesh->GetTetraList().GetNext(Pos);
if (Tetra->isIn_convexHull) continue;
int isoEdgeNum = 0;
for (int i = 0; i < 4; i++) {
if (Tetra->GetFaceRecordPtr(i + 1)->isLocatedIsoEdge == true) isoEdgeNum++;
}
if (isoEdgeNum == 0) continue;
else if (isoEdgeNum == 2 || isoEdgeNum == 1) std::cout << "Error! isoEdgeNum cannot equal to 1 or 2!" << std::endl << std::endl;
else if (isoEdgeNum == 3) {
QMeshFace* isoFace = new QMeshFace;
// build the face list
std::vector<QMeshFace*> FaceList; FaceList.resize(3);
int faceIndex = 0;
for (int i = 0; i < 4; i++) {
if (Tetra->GetFaceRecordPtr(i + 1)->isLocatedIsoEdge == true) {
FaceList[faceIndex] = Tetra->GetFaceRecordPtr(i + 1);
faceIndex++;
}
}
//sorting
bool firstDir = Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[0])); //detect which one should be the first node!!!
if (firstDir == true) {
if (FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[2]->installedIsoEdge->GetStartPoint()
|| FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[2]->installedIsoEdge->GetEndPoint()) {
std::swap(FaceList[1], FaceList[2]);
}
}
else {
if (FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[2]->installedIsoEdge->GetStartPoint()
|| FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[2]->installedIsoEdge->GetEndPoint()) {
std::swap(FaceList[1], FaceList[2]);
}
}
//using the first face and add its edge into the isoFace.
for (int i = 0; i < 3; i++) {
isoFace->SetEdgeRecordPtr(i, FaceList[i]->installedIsoEdge);
isoFace->SetDirectionFlag(i, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[i])));
if (Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[i])) == true)
FaceList[i]->installedIsoEdge->SetLeftFace(isoFace);
else FaceList[i]->installedIsoEdge->SetRightFace(isoFace);
}
//push this isoFace back to layer and compute norm
isoFace->SetEdgeNum(3);
isoFace->CalPlaneEquation();
isoFace->SetMeshPatchPtr(layer);
isoFace->SetIndexNo(layer->GetFaceList().GetCount() + 1);
layer->GetFaceList().AddTail(isoFace);
}
else if (isoEdgeNum == 4) {
std::vector<QMeshFace*> isoFace; isoFace.resize(2);
for (int i = 0; i < 2; i++) {
isoFace[i] = new QMeshFace;
}
// build the face list
std::vector<QMeshFace*> FaceList; FaceList.resize(4);
int faceIndex = 0;
for (int i = 0; i < 4; i++) FaceList[i] = Tetra->GetFaceRecordPtr(i + 1);
bool firstDir = Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[0])); //detect which one should be the first node!!!
//sorting edge
if (firstDir == true) {
for (int i = 0; i < 2; i++) {
if (FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[i + 2]->installedIsoEdge->GetStartPoint()
|| FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[i + 2]->installedIsoEdge->GetEndPoint()) {
std::swap(FaceList[1], FaceList[i + 2]);
}
}
if (FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[3]->installedIsoEdge->GetStartPoint()
|| FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[3]->installedIsoEdge->GetEndPoint()) {
}
else std::swap(FaceList[2], FaceList[3]);
}
else {
for (int i = 0; i < 2; i++) {
if (FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[i + 2]->installedIsoEdge->GetStartPoint()
|| FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[i + 2]->installedIsoEdge->GetEndPoint()) {
std::swap(FaceList[1], FaceList[i + 2]);
}
}
if (FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[3]->installedIsoEdge->GetStartPoint()
|| FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[3]->installedIsoEdge->GetEndPoint()) {
}
else std::swap(FaceList[2], FaceList[3]);
}
////test the sorting
//cout << Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[0])) << endl;
//for (int i = 0; i < 4; i++) {
// cout << FaceList[i]->installedIsoEdge->GetStartPoint()->GetIndexNo() << " , " <<
// FaceList[i]->installedIsoEdge->GetEndPoint()->GetIndexNo() << endl;
//}
QMeshEdge* midEdge1 = new QMeshEdge;
midEdge1->isMiddleEdge1 = true;
if (firstDir == true) {
midEdge1->SetStartPoint(FaceList[0]->installedIsoEdge->GetStartPoint());
if (FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[1]->installedIsoEdge->GetStartPoint())
midEdge1->SetEndPoint(FaceList[1]->installedIsoEdge->GetEndPoint());
else if (FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[1]->installedIsoEdge->GetEndPoint())
midEdge1->SetEndPoint(FaceList[1]->installedIsoEdge->GetStartPoint());
else std::cout << "Wrong case 1" << std::endl;
}
else {
midEdge1->SetStartPoint(FaceList[0]->installedIsoEdge->GetEndPoint());
if (FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[1]->installedIsoEdge->GetStartPoint())
midEdge1->SetEndPoint(FaceList[1]->installedIsoEdge->GetEndPoint());
else if (FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[1]->installedIsoEdge->GetEndPoint())
midEdge1->SetEndPoint(FaceList[1]->installedIsoEdge->GetStartPoint());
else std::cout << "Wrong case 2" << std::endl;
}
/*cout << "The midEdge" <<count << "- "<<midEdge1->GetStartPoint()->GetIndexNo() << " , " <<
midEdge1->GetEndPoint()->GetIndexNo() << endl;
cout << endl;*/
QMeshEdge* midEdge2 = new QMeshEdge;
midEdge2->isMiddleEdge = true;
if (firstDir == true) {
midEdge2->SetStartPoint(FaceList[0]->installedIsoEdge->GetEndPoint());
if (FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[3]->installedIsoEdge->GetStartPoint())
midEdge2->SetEndPoint(FaceList[3]->installedIsoEdge->GetEndPoint());
else if (FaceList[0]->installedIsoEdge->GetStartPoint() == FaceList[3]->installedIsoEdge->GetEndPoint())
midEdge2->SetEndPoint(FaceList[3]->installedIsoEdge->GetStartPoint());
else std::cout << "Wrong case 1" << std::endl;
}
else {
midEdge2->SetStartPoint(FaceList[0]->installedIsoEdge->GetStartPoint());
if (FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[3]->installedIsoEdge->GetStartPoint())
midEdge2->SetEndPoint(FaceList[3]->installedIsoEdge->GetEndPoint());
else if (FaceList[0]->installedIsoEdge->GetEndPoint() == FaceList[3]->installedIsoEdge->GetEndPoint())
midEdge2->SetEndPoint(FaceList[3]->installedIsoEdge->GetStartPoint());
else std::cout << "Wrong case 2" << std::endl;
}
/*cout << "The midEdge" <<count << "- "<<midEdge2->GetStartPoint()->GetIndexNo() << " , " <<
midEdge2->GetEndPoint()->GetIndexNo() << endl;
cout << endl;*/
//midEdge2->SetStartPoint(FaceList[0]->installedIsoEdge->GetEndPoint());
/*
bool dir = false;
if (FaceList[2]->installedIsoEdge->GetStartPoint() == FaceList[3]->installedIsoEdge->GetStartPoint()
|| FaceList[2]->installedIsoEdge->GetStartPoint() == FaceList[3]->installedIsoEdge->GetEndPoint()) {
midEdge2->SetEndPoint(FaceList[2]->installedIsoEdge->GetStartPoint());
dir = true;
}
else if(FaceList[2]->installedIsoEdge->GetEndPoint() == FaceList[3]->installedIsoEdge->GetStartPoint()
|| FaceList[2]->installedIsoEdge->GetEndPoint() == FaceList[3]->installedIsoEdge->GetEndPoint())
midEdge2->SetEndPoint(FaceList[2]->installedIsoEdge->GetEndPoint());
else cout << "Error!" << endl;*/
QMeshEdge* midEdge;
if (midEdge1->CalLength() <= midEdge2->CalLength()) {
midEdge = midEdge1;
isoFace[0]->SetEdgeRecordPtr(0, FaceList[0]->installedIsoEdge);
isoFace[0]->SetDirectionFlag(0, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[0])));
isoFace[0]->SetEdgeRecordPtr(1, FaceList[1]->installedIsoEdge);
isoFace[0]->SetDirectionFlag(1, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[1])));
isoFace[0]->SetEdgeRecordPtr(2, midEdge);
isoFace[0]->SetDirectionFlag(2, false);
for (int i = 0; i < 4; i++) {
if (i == 0 || i == 1) {
if (Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[i])) == true)
FaceList[i]->installedIsoEdge->SetLeftFace(isoFace[0]);
else FaceList[i]->installedIsoEdge->SetRightFace(isoFace[0]);
}
}
midEdge->SetRightFace(isoFace[0]);
isoFace[1]->SetEdgeRecordPtr(0, FaceList[2]->installedIsoEdge);
isoFace[1]->SetDirectionFlag(0, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[2])));
isoFace[1]->SetEdgeRecordPtr(1, FaceList[3]->installedIsoEdge);
isoFace[1]->SetDirectionFlag(1, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[3])));
isoFace[1]->SetEdgeRecordPtr(2, midEdge);
isoFace[1]->SetDirectionFlag(2, true);
for (int i = 0; i < 4; i++) {
if (i == 2 || i == 3) {
if (Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[i])) == true)
FaceList[i]->installedIsoEdge->SetLeftFace(isoFace[0]);
else FaceList[i]->installedIsoEdge->SetRightFace(isoFace[0]);
}
}
midEdge->SetLeftFace(isoFace[1]);
}
else {
midEdge = midEdge2;
//first triangle
isoFace[0]->SetEdgeRecordPtr(0, FaceList[0]->installedIsoEdge);
isoFace[0]->SetDirectionFlag(0, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[0])));
isoFace[0]->SetEdgeRecordPtr(1, midEdge);
isoFace[0]->SetDirectionFlag(1, true);
isoFace[0]->SetEdgeRecordPtr(2, FaceList[3]->installedIsoEdge);
isoFace[0]->SetDirectionFlag(2, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[3])));
//set edge right / left face
for (int i = 0; i < 4; i++) {
if (i == 0 || i == 3) {
if (Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[i])) == true)
FaceList[i]->installedIsoEdge->SetLeftFace(isoFace[0]);
else FaceList[i]->installedIsoEdge->SetRightFace(isoFace[0]);
}
}
midEdge->SetLeftFace(isoFace[0]);
//first triangle
isoFace[1]->SetEdgeRecordPtr(0, FaceList[1]->installedIsoEdge);
isoFace[1]->SetDirectionFlag(0, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[1])));
isoFace[1]->SetEdgeRecordPtr(1, FaceList[2]->installedIsoEdge);
isoFace[1]->SetDirectionFlag(1, Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[2])));
isoFace[1]->SetEdgeRecordPtr(2, midEdge);
isoFace[1]->SetDirectionFlag(2, false);
//set edge right / left face
for (int i = 0; i < 4; i++) {
if (i == 1 || i == 2) {
if (Tetra->IsNormalDirection(Tetra->GetFaceIndex(FaceList[i])) == true)
FaceList[i]->installedIsoEdge->SetLeftFace(isoFace[1]);
else FaceList[i]->installedIsoEdge->SetRightFace(isoFace[1]);
}
}
midEdge->SetRightFace(isoFace[1]);
}
//push back midEdge
midEdge->SetMeshPatchPtr(layer);
midEdge->SetIndexNo(layer->GetEdgeList().GetCount() + 1);
layer->GetEdgeList().AddTail(midEdge);
/*midEdge1->SetMeshPatchPtr(layer);
midEdge1->SetIndexNo(layer->GetEdgeList().GetCount() + 1);
layer->GetEdgeList().AddTail(midEdge1);*/
//midEdge2->SetMeshPatchPtr(layer);
//midEdge2->SetIndexNo(layer->GetEdgeList().GetCount() + 1);
//layer->GetEdgeList().AddTail(midEdge2);
//push this isoFace back to layer and compute norm
for (int i = 0; i < 2; i++) {
isoFace[i]->SetEdgeNum(3);
isoFace[i]->CalPlaneEquation();
isoFace[i]->SetMeshPatchPtr(layer);
isoFace[i]->SetIndexNo(layer->GetFaceList().GetCount() + 1);
layer->GetFaceList().AddTail(isoFace[i]);
}
}
}
//give each node face list
for (GLKPOSITION Pos = layer->GetFaceList().GetHeadPosition(); Pos;) {
QMeshFace* Face = (QMeshFace*)layer->GetFaceList().GetNext(Pos);
//if (Face->in_convexHull) continue;
for (int i = 0; i < 3; i++) {
QMeshNode* Node = Face->GetNodeRecordPtr(i);
Node->GetFaceList().AddTail(Face);
}
}
return layer;
}
void IsoLayerGeneration::smoothingIsoSurface(PolygenMesh* isoSurface) {
for (GLKPOSITION posMesh = isoSurface->GetMeshList().GetHeadPosition(); posMesh != nullptr;) {
QMeshPatch* isoLayer = (QMeshPatch*)isoSurface->GetMeshList().GetNext(posMesh);
for (GLKPOSITION Pos = isoLayer->GetEdgeList().GetHeadPosition(); Pos;) {
QMeshEdge* thisEdge = (QMeshEdge*)isoLayer->GetEdgeList().GetNext(Pos);
if (thisEdge->IsBoundaryEdge()) {
thisEdge->GetStartPoint()->isoSurfaceBoundary = true;
thisEdge->GetEndPoint()->isoSurfaceBoundary = true;
}
}
//laplacian smoothness
for (GLKPOSITION Pos = isoLayer->GetNodeList().GetHeadPosition(); Pos;) {
QMeshNode* thisNode = (QMeshNode*)isoLayer->GetNodeList().GetNext(Pos);
if (thisNode->isoSurfaceBoundary) continue;
else {
double pp[3] = { 0 }; int neighNum = 0;
for (GLKPOSITION Pos = thisNode->GetEdgeList().GetHeadPosition(); Pos;) {
QMeshEdge* neighEdge = (QMeshEdge*)thisNode->GetEdgeList().GetNext(Pos);
QMeshNode* neighNode = neighEdge->GetStartPoint();
if (neighNode == thisNode) neighNode = neighEdge->GetEndPoint();
double p1[3];
neighNode->GetCoord3D(p1[0], p1[1], p1[2]);
for (int i = 0; i < 3; i++) pp[i] += p1[i];
neighNum++;
}
for (int i = 0; i < 3; i++) pp[i] /= neighNum;
thisNode->SetCoord3D(pp[0], pp[1], pp[2]);
}
}
}
}
void IsoLayerGeneration::outputSurfaceMesh(PolygenMesh* isoSurface, bool isRun, std::string outFolderName, int _fileOffset) {
if (!isRun) return;
for (GLKPOSITION posMesh = isoSurface->GetMeshList().GetHeadPosition(); posMesh != nullptr;) {
QMeshPatch* each_layer = (QMeshPatch*)isoSurface->GetMeshList().GetNext(posMesh);
std::string LAYER_dir = "../DataSet/CURVED_LAYER/IN/" + std::to_string(each_layer->GetIndexNo() + _fileOffset);
if (_fileOffset == 0)
LAYER_dir = "../DataSet/CURVED_LAYER/OUT/" + std::to_string(each_layer->GetIndexNo()+_fileOffset);
output_OneSurfaceMesh(each_layer, LAYER_dir);
}
std::cout << "Finish output layers into : " << ".. / DataSet / CURVED_LAYER /" << std::endl;
}
void IsoLayerGeneration::output_OneSurfaceMesh(QMeshPatch* isoSurface, std::string path) {
double pp[3];
path += ".obj";
std::ofstream nodeSelection(path);
int index = 0;
for (GLKPOSITION posNode = isoSurface->GetNodeList().GetHeadPosition(); posNode != nullptr;) {
QMeshNode* node = (QMeshNode*)isoSurface->GetNodeList().GetNext(posNode);
node->GetCoord3D(pp[0], pp[1], pp[2]);
nodeSelection << "v " << pp[0] << " " << pp[1] << " " << pp[2] << std::endl;
index++; node->SetIndexNo(index);
}
for (GLKPOSITION posFace = isoSurface->GetFaceList().GetHeadPosition(); posFace != nullptr;) {
QMeshFace* face = (QMeshFace*)isoSurface->GetFaceList().GetNext(posFace);
nodeSelection << "f " << face->GetNodeRecordPtr(0)->GetIndexNo()
<< " " << face->GetNodeRecordPtr(1)->GetIndexNo()
<< " " << face->GetNodeRecordPtr(2)->GetIndexNo() << std::endl;
}
nodeSelection.close();
}
void IsoLayerGeneration::reoOrderLayers(PolygenMesh* isoSurface)
{
std::vector<QMeshPatch*> newMeshListVector;
int TotalCount = isoSurface->GetMeshList().GetCount();
newMeshListVector.reserve(TotalCount);
for (GLKPOSITION meshPos = isoSurface->GetMeshList().GetHeadPosition(); meshPos;) {
QMeshPatch* meshPatch = (QMeshPatch*)isoSurface->GetMeshList().GetNext(meshPos);
newMeshListVector.push_back(meshPatch);
}
isoSurface->GetMeshList().RemoveAll();
for (auto iterator_ = newMeshListVector.rbegin(); iterator_ != newMeshListVector.rend(); iterator_++) {
QMeshPatch* insertPatch = *iterator_;
insertPatch->SetIndexNo(isoSurface->GetMeshList().GetCount());
isoSurface->GetMeshList().AddTail(insertPatch);
}
}
bool IsoLayerGeneration::planeCutSurfaceMesh_delete(QMeshPatch* surfaceMesh, double last_dist, int dirIndex) {
//printf("--- begin cut the mesh by convex hull plane \n\n");
int cutFaceCase[3][9] = {
{ 1,4,5,1,2,4,4,3,5 },
{ 1,4,5,4,2,5,2,3,5 },
{ 1,4,5,4,2,5,1,5,3 } };
// Plane equation: Ax+By+Cz+D = 0
Eigen::Vector3d PlaneDir; double D = last_dist;
switch (dirIndex) {
case 0:
PlaneDir << 1.0, 0.0, 0.0;
break;
case 1:
PlaneDir << -1.0, 0.0, 0.0;
break;
case 2:
PlaneDir << 0.0, 1.0, 0.0;
break;
case 3:
PlaneDir << 0.0, -1.0, 0.0;
break;
case 4:
PlaneDir << 0.0, 0.0, 1.0;
break;
case 5:
PlaneDir << 0.0, 0.0, -1.0;
break;
}
//std::cout << PlaneDir[0] << " " << PlaneDir[1] << " " << PlaneDir[2] << std::endl;
//--------------------------------------------------------------
/* pre-process to compute node-plane distance*/
int positiveNodeNum = 0; int negativeNodeNum = 0;
for (GLKPOSITION Pos = surfaceMesh->GetNodeList().GetHeadPosition(); Pos;) {
QMeshNode* Node = (QMeshNode*)surfaceMesh->GetNodeList().GetNext(Pos);
Eigen::Vector3d pp; Node->GetCoord3D(pp(0), pp(1), pp(2));
Node->nodePlaneDis = pp.dot(PlaneDir) - D;
if (Node->nodePlaneDis > 0) {
positiveNodeNum++; Node->SetIndexNo(-1);
}
else {
Node->SetIndexNo(negativeNodeNum); negativeNodeNum++; // node index start from 0
}
}
if (positiveNodeNum == 0) return true; //do not do anything
else if (negativeNodeNum == 0) {
//surfaceMesh->ClearAll();
return false; //delete this layer
}
//--------------------------------------------------------------
/* detect the intersect edge, build intersect node*/
std::cout << "Cutting...\n";
int cutNodeIndex = 0;
for (GLKPOSITION Pos = surfaceMesh->GetEdgeList().GetHeadPosition(); Pos;) {
QMeshEdge* thisEdge = (QMeshEdge*)surfaceMesh->GetEdgeList().GetNext(Pos);
double a = thisEdge->GetStartPoint()->nodePlaneDis;
double b = thisEdge->GetEndPoint()->nodePlaneDis;
if (a * b > 0) continue;
double alpha = fabs(a) / fabs(b - a);
double p1[3], p2[3], pp[3];
thisEdge->GetStartPoint()->GetCoord3D(p1[0], p1[1], p1[2]);
thisEdge->GetEndPoint()->GetCoord3D(p2[0], p2[1], p2[2]);
for (int j = 0; j < 3; j++)
pp[j] = (1.0 - alpha) * p1[j] + alpha * p2[j];
QMeshNode* isoNode = new QMeshNode;
isoNode->SetMeshPatchPtr(surfaceMesh);
isoNode->SetCoord3D(pp[0], pp[1], pp[2]);
//std::cout << pp[0] << "," << pp[1] << "," << pp[2] << std::endl;
surfaceMesh->GetNodeList().AddTail(isoNode);
isoNode->planeCutNewNode = true;
isoNode->SetIndexNo(negativeNodeNum + cutNodeIndex); // index start from 0
cutNodeIndex++;
thisEdge->intersectNodeIndex = isoNode->GetIndexNo(); // if exist, the node index will large than 0
}
//std::cout << "finish generate the cutting node" << std::endl;
///* Build topology */
// -- node table
float* nodeTable;
int nodeNum = surfaceMesh->GetNodeNumber() - positiveNodeNum;
nodeTable = (float*)malloc(sizeof(float) * nodeNum * 3);
for (GLKPOSITION Pos = surfaceMesh->GetNodeList().GetHeadPosition(); Pos;) {
QMeshNode* Node = (QMeshNode*)surfaceMesh->GetNodeList().GetNext(Pos);
if (Node->GetIndexNo() < 0) continue; //delete those face have node on the left plane
double pp[3]; Node->GetCoord3D(pp[0], pp[1], pp[2]);
for (int i = 0; i < 3; i++) nodeTable[Node->GetIndexNo() * 3 + i] = (float)pp[i];
//std::cout << pp[0] << "," << pp[1] << "," << pp[2] << std::endl;
}
// -- face table
int faceNum = 0;
for (GLKPOSITION Pos = surfaceMesh->GetFaceList().GetHeadPosition(); Pos;) {
QMeshFace* face = (QMeshFace*)surfaceMesh->GetFaceList().GetNext(Pos);
int face_posNodeNum = 0;
for (int i = 0; i < 3; i++) {
if (face->GetNodeRecordPtr(i)->nodePlaneDis > 0) face_posNodeNum++;
}
if (face_posNodeNum == 0 || face_posNodeNum == 2) faceNum += 1;
else if (face_posNodeNum == 1) faceNum += 2;
}
unsigned int* faceTable;
faceTable = (unsigned int*)malloc(sizeof(unsigned int) * faceNum * 3);
int faceNodeIndex = 0;
for (GLKPOSITION Pos = surfaceMesh->GetFaceList().GetHeadPosition(); Pos;) {
QMeshFace* face = (QMeshFace*)surfaceMesh->GetFaceList().GetNext(Pos);
int face_posNodeNum = 0;
for (int i = 0; i < 3; i++) {
if (face->GetNodeRecordPtr(i)->nodePlaneDis > 0) face_posNodeNum++;
}
if (face_posNodeNum == 3) continue;
else if (face_posNodeNum == 0) {
for (int i = 0; i < 3; i++)
faceTable[faceNodeIndex + i] = face->GetNodeRecordPtr(i)->GetIndexNo();
faceNodeIndex += 3; continue;
}
int nodeIndexArray[5] = { 0 }; int noCutEdgeIndex = -1; int cutEdgeIndex = 0;
for (int i = 0; i < 3; i++)
nodeIndexArray[i] = face->GetNodeRecordPtr(i)->GetIndexNo();
for (int i = 0; i < 3; i++) {
if (face->GetEdgeRecordPtr(i + 1)->intersectNodeIndex < 0) {
noCutEdgeIndex = i; continue;
}
else {
nodeIndexArray[3 + cutEdgeIndex] = face->GetEdgeRecordPtr(i + 1)->intersectNodeIndex;
cutEdgeIndex++;
}
}
if (face_posNodeNum == 1) {
int positiveNodeIndex = -1;
for (int i = 0; i < 3; i++) {
if (face->GetNodeRecordPtr(i)->nodePlaneDis > 0) positiveNodeIndex = i;
}
for (int i = 0; i < 3; i++) { //case
if (noCutEdgeIndex == i) {
int addFaceIndex = 0;
for (int j = 0; j < 3; j++) { //face
bool keepThisFace = true;
for (int k = 0; k < 3; k++) {
int currentNodeIndex = cutFaceCase[i][3 * j + k] - 1;
if (currentNodeIndex == positiveNodeIndex) keepThisFace = false;
}
if (keepThisFace == false) continue;
for (int k = 0; k < 3; k++) //node
faceTable[faceNodeIndex + 3 * addFaceIndex + k] = nodeIndexArray[cutFaceCase[i][3 * j + k] - 1];
addFaceIndex++;
}
}
}
faceNodeIndex += 6;
}
else if (face_posNodeNum == 2) {
int negativeNodeIndex = -1;
for (int i = 0; i < 3; i++) {
if (face->GetNodeRecordPtr(i)->nodePlaneDis < 0) negativeNodeIndex = i;
}
for (int i = 0; i < 3; i++) { //case
if (noCutEdgeIndex == i) {
for (int j = 0; j < 3; j++) { //face
bool keepThisFace = false;
for (int k = 0; k < 3; k++) {
int currentNodeIndex = cutFaceCase[i][3 * j + k] - 1;
if (currentNodeIndex == negativeNodeIndex) keepThisFace = true;
}
if (keepThisFace == false) continue;
for (int k = 0; k < 3; k++) //node
faceTable[faceNodeIndex + k] = nodeIndexArray[cutFaceCase[i][3 * j + k] - 1];
}
}
}
faceNodeIndex += 3;
}
}
surfaceMesh->ClearAll();
surfaceMesh->constructionFromVerFaceTable(nodeNum, nodeTable, faceNum, faceTable);
free(nodeTable);
free(faceTable);
return true;
//printf("--- finish cut mesh by plane ---------");
}ac2468ac8This file is pinned to the selected release. Download the original to open it in your design tool.