diff --git a/src/main.cc b/src/main.cc index 1781e54..25db38b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -92,10 +92,10 @@ Controls refinement along lines or around polygons. Each shape is defined by a s 4. Topography Control Format Controls refinement based on elevation data. The refinement is based on elevation variation within triangles: -# First line: +# First line: STD|MAX [] # Following lines: # maximum-STD: Maximum allowed standard deviation of elevation within a triangle -200.0 10 -1 5 +STD 10 -1 5 200.0 -179.95 89.95 -4203.20 -179.85 89.95 -4203.07 -179.75 89.95 -4203.47 @@ -168,7 +168,8 @@ int main(int argc, char* argv[]){ case '?': //处理未定义或错误参数 if (optopt == 'd' || optopt == 'r' || optopt == 'o' || optopt == 'm' || optopt == 'n' || optopt == 'v' || optopt == 't' || optopt == 'p' || optopt == 'l' - || optopt == 'g' || optopt == 'c' || optopt == 's' || optopt == 'k'){ + || optopt == 'g' || optopt == 'c' || optopt == 's' || optopt == 'k' + || optopt == 'z'){ fprintf (stderr, "Option -%c requires an argument.\n", optopt); return 0; } diff --git a/src/struct_functions.cc b/src/struct_functions.cc index 9e6705c..58882f9 100644 --- a/src/struct_functions.cc +++ b/src/struct_functions.cc @@ -156,7 +156,7 @@ int LocalIndex(int id, Triangle t) return -1; } -double data_std(const vector &data) +double TopoSTD(const vector &data) { if (data.size() == 0) return 0.0; @@ -170,4 +170,15 @@ double data_std(const vector &data) sq_sum += (data[i] - mean)*(data[i] - mean); return sqrt(sq_sum / data.size()); +} + +double TopoMax(const vector &data) +{ + double max = data[0]; + for (size_t i = 0; i < data.size(); i++) + { + if (data[i] > max) max = data[i]; + } + + return max; } \ No newline at end of file diff --git a/src/struct_functions.h b/src/struct_functions.h index ceb10d7..4a5328a 100644 --- a/src/struct_functions.h +++ b/src/struct_functions.h @@ -59,9 +59,16 @@ struct ControlPoint{ }; typedef vector ControlPointArray; +enum topo_cnst_e +{ + STD, + MAX, +}; + struct ControlTopo{ int id = -1, max_depth = -1, physic_group = 0; double minimal_resolution = DBL_MAX; + topo_cnst_e cnst_type; VertexArray vert; // verts for topo vector topo; }; @@ -96,5 +103,6 @@ Vertex RotateVertex(Vertex,Vertex,Vertex); Cpoint LineCrossPlane(Cpoint,Cpoint,Cpoint); string GetStringIndex(Vertex); int LocalIndex(int,Triangle); -double data_std(const vector &data); +double TopoSTD(const vector &data); +double TopoMax(const vector &data); #endif \ No newline at end of file diff --git a/src/stt_class.h b/src/stt_class.h index 03daf25..89963e1 100644 --- a/src/stt_class.h +++ b/src/stt_class.h @@ -34,8 +34,8 @@ public: int InTriangleLine(QuadTreeNode*);//判断插入线是否穿过节点三角形 使用的是球面下的方法 直接矢量计算 注意因为球面上的特殊关系 两个点之间的夹角不能大于等于180度 因为球面上总是沿着最短路径走 而且通常我们指的也是最短路径 int InTrianglePolygon(QuadTreeNode*);//判断多边形与三角形的关系 int InTriangleCircle(QuadTreeNode*);//判断圆与三角形的关系 - int InTriangleTopo(QuadTreeNode*, const ControlTopo& in_topo, double diff_threshold);//判断地形与三角形的关系 - int InTriangleTopoSet(QuadTreeNode*, const ControlTopo& in_topo, ControlTopo& out_topo); + int InTriangleTopo(QuadTreeNode*, const ControlTopo& in_topo, double diff_threshold); //判断地形与三角形的关系 + int InTriangleTopoSet(QuadTreeNode*, const ControlTopo& in_topo, ControlTopo& out_topo); // 整理节点三角形内的地形点数组 int OutPolyOutline(QuadTreeNode*);//判断多边形与三角形的关系 用于切割模型边界 int InPolyOutline(QuadTreeNode*);//判断多边形与三角形的关系 用于切割模型边界 挖洞 int OutputMshFile(char*,double,double); @@ -79,6 +79,6 @@ private: ControlLineArray array_outline_polygon_; ControlLineArray array_hole_polygon_; // threshold for topography constraint - double topo_max_diff_; + double topo_thres_; }; #endif \ No newline at end of file diff --git a/src/stt_create_branch.cc b/src/stt_create_branch.cc index b72760a..52fe9f9 100644 --- a/src/stt_create_branch.cc +++ b/src/stt_create_branch.cc @@ -24,7 +24,7 @@ void SttGenerator::CreateBranch(int upper_id,int order_id,int depth,int t_ids0,i || InTrianglePolygon(current_node) || InTriangleLine(current_node) || InTrianglePoint(current_node) - || InTriangleTopo(current_node, out_topo, topo_max_diff_)) + || InTriangleTopo(current_node, out_topo, topo_thres_)) && depth < max_depth_) //最大深度限制 所有节点不能超过的深度 { ivd_ = map_id_vertex_.find(t_ids0);//利用map_ID映射找到四叉树节点的前三个点,这三个节点是上一层四叉树产生的,必然存在 diff --git a/src/stt_get_control_topo.cc b/src/stt_get_control_topo.cc index 2ca553e..35ea4e9 100644 --- a/src/stt_get_control_topo.cc +++ b/src/stt_get_control_topo.cc @@ -4,7 +4,7 @@ int SttGenerator::GetControlTopography(char* filename) { double one_topo; stringstream temp_ss; - string temp_str; + string temp_str, cnst_str; Vertex temp_vert; ifstream infile; @@ -16,7 +16,20 @@ int SttGenerator::GetControlTopography(char* filename) if (*(temp_str.begin()) == '#' || temp_str == "") continue; else{ temp_ss = Str2Ss(temp_str); - temp_ss >> topo_max_diff_ >> control_topo_.max_depth >> control_topo_.minimal_resolution >> control_topo_.physic_group; + + temp_ss >> cnst_str; + if (cnst_str == "STD") + { + control_topo_.cnst_type = STD; + temp_ss >> control_topo_.max_depth >> control_topo_.minimal_resolution >> control_topo_.physic_group >> topo_thres_; + } + else if (cnst_str == "MAX") + { + control_topo_.cnst_type = MAX; + temp_ss >> control_topo_.max_depth >> control_topo_.minimal_resolution >> control_topo_.physic_group; + } + else throw std::runtime_error("[stt::get_control_topography] Invalid topography constrain type."); + if (control_topo_.max_depth <= 0) control_topo_.max_depth = 1e+3; //这里直接给一个很大的深度值 节点深度一定小于这个值 if (control_topo_.minimal_resolution <= 0) control_topo_.minimal_resolution = -1.0; //这里直接给成-1 break; diff --git a/src/stt_in_triangle_topo.cc b/src/stt_in_triangle_topo.cc index bbb8c80..84028db 100644 --- a/src/stt_in_triangle_topo.cc +++ b/src/stt_in_triangle_topo.cc @@ -24,14 +24,30 @@ int SttGenerator::InTriangleTopo(QuadTreeNode* node, const ControlTopo& in_topo, } node_resolution = node_resolution*60/Pi; - if (in_topo.max_depth >= node_depth && - node_resolution >= in_topo.minimal_resolution && - data_std(in_topo.topo) >= diff_threshold) + if (control_topo_.cnst_type == STD) { - // 将控制点的组别赋值给当前节点 - node->tri.physic_group = in_topo.physic_group; - return 1; + if (in_topo.max_depth >= node_depth && + node_resolution >= in_topo.minimal_resolution && + TopoSTD(in_topo.topo) >= diff_threshold) + { + // 将控制点的组别赋值给当前节点 + node->tri.physic_group = in_topo.physic_group; + return 1; + } + else return 0; } - else return 0; + else if (control_topo_.cnst_type == MAX) + { + if (in_topo.max_depth >= node_depth && + node_resolution >= in_topo.minimal_resolution && + TopoMax(in_topo.topo) >= node_depth) + { + // 将控制点的组别赋值给当前节点 + node->tri.physic_group = in_topo.physic_group; + return 1; + } + else return 0; + } + else throw std::runtime_error("[stt::in_triangle_topo] Invalid topography constrain type."); } } \ No newline at end of file