You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
7.3 KiB

1 year ago
#pragma once
#include "FillBoundary_fwd.hpp"
#include "KDTree.hpp"
#include "KDTreeMutable.hpp"
#include <iomanip>
#include <random>
#include <map>
namespace meshless {
DomainDiscretization<Eigen::Vector3d> discretizeBoundaryWithDensity(const OccShape& shape, const std::function<double(Eigen::Vector3d)>& h, int type) {
if(type == 0)type = -1;
std::mt19937 gen(shape.seed_);
DomainDiscretization<Eigen::Vector3d> domainGlobal(shape);
KDTreeMutable treeGlobal;
TopExp_Explorer expFace(shape.myShape, TopAbs_FACE);
int numFace = 0;
std::cout.precision(10);
for(; expFace.More(); expFace.Next()) {
std::cout << "������ɢ����" << ++numFace << "������" << std::endl;
//if(numFace != 5)continue;
bool reverseNormal = false;
const TopoDS_Face& face = TopoDS::Face(expFace.Current());
Handle(Geom_Surface) geomSurface = BRep_Tool::Surface(face);
if(face.Orientable() == TopAbs_REVERSED) {
std::cout << "���淨���跴��\n";
reverseNormal = true;
}
//��ʼ��ɢ��ÿ��wire
auto outerWire = BRepTools::OuterWire(face);
int numWire = 0;
TopExp_Explorer expWire(face, TopAbs_WIRE);
for(; expWire.More(); expWire.Next()) {
std::cout << "������ɢ����" << ++numWire << "��Wire" << std::endl;
const TopoDS_Wire& wire = TopoDS::Wire(expWire.Current());
if(wire == outerWire) {
std::cout << "��wireΪ�⻷\n";
}
DomainDiscretization<Eigen::Vector2d> domainParamLocalPatch(shape);
TopExp_Explorer expEdge(wire, TopAbs_EDGE);
int numEdge = 0;
int genPoints = 0;
for(; expEdge.More(); expEdge.Next()) {
std::cout << "������ɢ����" << ++numEdge << "��Edge" << std::endl;
//if(numEdge != 5)continue;
const TopoDS_Edge& edge = TopoDS::Edge(expEdge.Current());
KDTreeMutable treeLocal;
Standard_Real firstParam, lastParam;
Handle(Geom_Curve) geomCurve = BRep_Tool::Curve(edge, firstParam, lastParam);
//std::cout << "param: " << firstParam << " -> " << lastParam << '\n';
//���߲������������������ϵ�����
Standard_Real pCurveFirstParam, pCurveLastParam;
Handle(Geom2d_Curve) geomPCurve = BRep_Tool::CurveOnSurface(edge, face, pCurveFirstParam, pCurveLastParam);
Handle(Geom2d_TrimmedCurve) geomTrimmedCurve = new Geom2d_TrimmedCurve(geomPCurve, pCurveFirstParam, pCurveLastParam);
//GeomTools::Dump(geomCurve, std::cout);
//std::cout << "In param Pcurve:\n";
//GeomTools::Dump(geomPCurve, std::cout);
std::cout << "GeomPcurve P:" << pCurveFirstParam << ',' << pCurveLastParam << '\n';
std::uniform_real_distribution<> dis(pCurveFirstParam, pCurveLastParam);
//���߲�����
double tSeedInParam = dis(gen);
gp_Pnt2d tSeedInPCurve;
geomPCurve->D0(tSeedInParam, tSeedInPCurve);
//std::cout << "t in param: " << tSeedInParam << "\n";
//std::cout << "t in PCurve: " << tSeedInPCurve.Coord().X() << "," << tSeedInPCurve.Coord().Y() << "\n";
//!�������ּ��㷽���õ��Ľ�����һ�£���һ�ָ�׼ȷ
gp_Pnt tSeedInCurve;
geomCurve->D0(tSeedInParam, tSeedInCurve);
gp_Pnt tSeedInSurf;
geomSurface->D0(tSeedInPCurve.X(), tSeedInPCurve.Y(), tSeedInSurf);
//! Tip: use GeomLib::NormEstim() to calculate surface normal at specified (U, V) point.
std::cout << "t in Surface:#1 " << tSeedInCurve.Coord().X() << "," << tSeedInCurve.Coord().Y() << "," << tSeedInCurve.Coord().Z() << "\n";
std::cout << "t in Surface:#2 " << tSeedInSurf.Coord().X() << "," << tSeedInSurf.Coord().Y() << "," << tSeedInSurf.Coord().Z() << "\n";
Eigen::Vector3d eigenSeedPnt(tSeedInCurve.X(), tSeedInCurve.Y(), tSeedInCurve.Z());
Eigen::Vector2d eigenSeedPntParam(tSeedInPCurve.X(), tSeedInPCurve.Y());
domainParamLocalPatch.addInternalNodeWithT(transPnt2d(tSeedInPCurve), tSeedInParam, 1);
treeLocal.insert(transPnt(tSeedInCurve));
//Insert into global structures.
double checkRadiusSeed = h(eigenSeedPnt);
double d_sq = treeGlobal.size() == 0 ? 10 * checkRadiusSeed * checkRadiusSeed : treeGlobal.query(eigenSeedPnt).second[0];
if(d_sq >= (shape.zeta * checkRadiusSeed) * (shape.zeta * checkRadiusSeed)) {
//domainGlobal.addBoundaryNode(eigenSeedPnt, -1);
gp_Dir tSeedNormal;
auto retStatus = GeomLib::NormEstim(geomSurface, tSeedInPCurve, 1e-6, tSeedNormal);
if(retStatus >= 2) {
std::cout << "calculate wrong!\n";
exit(-1);
}
if(reverseNormal) tSeedNormal = -tSeedNormal;
Eigen::Vector3d eigenNormal(tSeedNormal.X(), tSeedNormal.Y(), tSeedNormal.Z());
domainGlobal.addBoundaryNode(eigenSeedPnt, type, eigenNormal);
treeGlobal.insert(eigenSeedPnt);
}
int curNode = domainParamLocalPatch.size() - 1;
int endNode = domainParamLocalPatch.size();
while(curNode < endNode && endNode < shape.max_points) {
genPoints++;
//std::cout << "curNode / endNode : " << curNode << '/' << endNode << '\n';
auto param = domainParamLocalPatch.pos(curNode);
double t = domainParamLocalPatch.getT(curNode);
std::vector<double> candidates{ 1.0, -1.0 };
gp_Pnt pt;
gp_Vec der;
geomCurve->D1(t, pt, der);
std::cout << "pt: " << pt.X() << "," << pt.Y() << "," << pt.Z() << '\n';
std::cout << "der: " << der.X() << "," << der.Y() << "," << der.Z() << '\n';
std::cout << "der.Mag:" << der.Magnitude() << '\n';
double alpha = h(transPnt(pt)) / der.Magnitude();
for(const auto& uCan : candidates) {
double tNew = t + alpha * uCan;
if(tNew > pCurveLastParam || tNew < pCurveFirstParam) {
std::cout << "�ų�\n";
continue;
}
std::cout << "tNew:" << tNew << "\n";
gp_Pnt2d tNewSeedInPCurve;
geomPCurve->D0(tNew, tNewSeedInPCurve);
gp_Pnt ptNew;
geomCurve->D0(tNew, ptNew);
gp_Pnt ptNew2;
geomSurface->D0(tNewSeedInPCurve.X(), tNewSeedInPCurve.Y(), ptNew2);
std::cout << "ptNew: " << ptNew.X() << "," << ptNew.Y() << "," << ptNew.Z() << '\n';
std::cout << "ptNew2: " << ptNew2.X() << "," << ptNew2.Y() << "," << ptNew2.Z() << '\n';
double checkradius = pt.SquareDistance(ptNew);
std::cout << "CheckRadius: " << checkradius << '\n';
double d_sq_loc = treeLocal.query(transPnt(ptNew)).second[0];
std::cout << "d_sq_loc: " << d_sq_loc << '\n';
if(d_sq_loc >= (shape.zeta * shape.zeta * checkradius)) {
domainParamLocalPatch.addInternalNodeWithT(transPnt2d(tNewSeedInPCurve), tNew, 1);
treeLocal.insert(transPnt(ptNew));
endNode++;
double d_sq_global = treeGlobal.query(transPnt(ptNew)).second[0];
if(d_sq_global >= (shape.zeta * shape.zeta * checkradius)) {
gp_Dir tSeedNormalNew;
auto retStatus = GeomLib::NormEstim(geomSurface, tNewSeedInPCurve, 1e-6, tSeedNormalNew);
if(retStatus >= 2) {
std::cout << "calculate wrong!\n";
exit(-1);
}
if(reverseNormal) {
tSeedNormalNew = -tSeedNormalNew;
}
domainGlobal.addBoundaryNode(transPnt(ptNew), type, transVec(tSeedNormalNew));
treeGlobal.insert(transPnt(ptNew));
} else {
std::cout << "ȫ�ֲ����ӵ�\n";
}
} else {
std::cout << "�ֲ������ӵ�\n";
}
}
curNode++;
}
std::cout << "�ñ��Ѿ����ɣ�" << genPoints << "����\n";
}
}
//fill boundary surface!
KDTree paramBoundarySearch;
}
return domainGlobal;
}
};