Browse Source

fix: 'compute_polyline_bottom/top_cap_matrix' and 'update_geometry'

main
linchforever 2 days ago
parent
commit
6065f7860d
  1. 3
      primitive_process/interface/base/primitive.hpp
  2. 34
      primitive_process/interface/primitive/simple/extrude.hpp
  3. 7
      primitive_process/interface/primitive/simple/sphere.hpp
  4. 2
      primitive_process/src/base/primitive.cpp
  5. 41
      primitive_process/src/primitive/simple/extrude.cpp

3
primitive_process/interface/base/primitive.hpp

@ -25,8 +25,7 @@ EXTERN_C struct PE_API primitive {
virtual span<marked_subface_ptr_t<subface>> get_subfaces() const = 0; virtual span<marked_subface_ptr_t<subface>> get_subfaces() const = 0;
virtual stl_vector_mp<surface_type> get_subface_types() const = 0; virtual stl_vector_mp<surface_type> get_subface_types() const = 0;
virtual stl_vector_mp<const void *> get_subface_geometries() const = 0; virtual stl_vector_mp<const void *> get_subface_geometries() const = 0;
virtual void update_geometry(const void *geometry_ptr, size_t subface_index = 0);
void update_geometry(const void *geometry_ptr, size_t subface_index = 0);
dynamic_bitset_mp<> judge_sign_by_subface_sign(const stl_vector_mp<dynamic_bitset_mp<>> &) const; dynamic_bitset_mp<> judge_sign_by_subface_sign(const stl_vector_mp<dynamic_bitset_mp<>> &) const;
dynamic_bitset_mp<> judge_sign_by_subface_sign(const stl_vector_mp<dynamic_bitset_mp<>> &, dynamic_bitset_mp<> judge_sign_by_subface_sign(const stl_vector_mp<dynamic_bitset_mp<>> &,

34
primitive_process/interface/primitive/simple/extrude.hpp

@ -163,15 +163,16 @@ inline vector2d compute_profile_aabb_max(const polyline_descriptor_t* profile)
* @param desc polyline descriptor * @param desc polyline descriptor
* @return paired_model_matrix * @return paired_model_matrix
*/ */
inline paired_model_matrix compute_polyline_bottom_cap_matrix(const polyline_descriptor_t& desc) inline paired_model_matrix compute_polyline_bottom_cap_matrix(const extrude_polyline_geometry_t& geom)
{ {
Eigen::Vector3d origin = Eigen::Map<const Eigen::Vector3d>(&desc.points[0].x); const Eigen::Vector2d tangent_2d = geom.axis_geom.calculate_tangent(0.0);
Eigen::Vector3d p1 = Eigen::Map<const Eigen::Vector3d>(&desc.points[1].x); const Eigen::Vector3d tangent_3d =
Eigen::Vector3d tangent = (p1 - origin).normalized(); (geom.axis_to_world.linear() * Eigen::Vector3d(tangent_2d.y(), 0.0, tangent_2d.x())).normalized();
Eigen::Vector3d axis_normal = Eigen::Map<const Eigen::Vector3d>(&desc.reference_normal.x); const Eigen::Vector3d origin = Eigen::Map<const Eigen::Vector3d>(&geom.descriptor.axis.points[0].x);
Eigen::Vector3d axis_normal = Eigen::Map<const Eigen::Vector3d>(&geom.descriptor.axis.reference_normal.x);
axis_normal.normalize(); axis_normal.normalize();
return build_polyline_cap_matrix(origin, tangent, axis_normal, false); return build_polyline_cap_matrix(origin, tangent_3d, axis_normal, false);
} }
/** /**
@ -179,16 +180,18 @@ inline paired_model_matrix compute_polyline_bottom_cap_matrix(const polyline_des
* @param desc polyline descriptor * @param desc polyline descriptor
* @return paired_model_matrix * @return paired_model_matrix
*/ */
inline paired_model_matrix compute_polyline_top_cap_matrix(const polyline_descriptor_t& desc) inline paired_model_matrix compute_polyline_top_cap_matrix(const extrude_polyline_geometry_t& geom)
{ {
uint32_t last_idx = desc.point_number - 1; const double segment_count = static_cast<double>(geom.axis_geom.start_indices.size());
Eigen::Vector3d origin = Eigen::Map<const Eigen::Vector3d>(&desc.points[last_idx].x); const Eigen::Vector2d tangent_2d = geom.axis_geom.calculate_tangent(segment_count);
Eigen::Vector3d p_prev = Eigen::Map<const Eigen::Vector3d>(&desc.points[last_idx - 1].x); const Eigen::Vector3d tangent_3d =
Eigen::Vector3d tangent = (origin - p_prev).normalized(); (geom.axis_to_world.linear() * Eigen::Vector3d(tangent_2d.y(), 0.0, tangent_2d.x())).normalized();
Eigen::Vector3d axis_normal = Eigen::Map<const Eigen::Vector3d>(&desc.reference_normal.x); const uint32_t last_idx = geom.descriptor.axis.point_number - 1;
const Eigen::Vector3d origin = Eigen::Map<const Eigen::Vector3d>(&geom.descriptor.axis.points[last_idx].x);
Eigen::Vector3d axis_normal = Eigen::Map<const Eigen::Vector3d>(&geom.descriptor.axis.reference_normal.x);
axis_normal.normalize(); axis_normal.normalize();
return build_polyline_cap_matrix(origin, tangent, axis_normal, true); return build_polyline_cap_matrix(origin, tangent_3d, axis_normal, true);
} }
/** /**
@ -223,7 +226,6 @@ inline paired_model_matrix make_helixline_cap_matrix(const helixline_geometry_da
return m; return m;
} }
inline paired_model_matrix compute_helixline_bottom_cap_matrix(const helixline_geometry_data& ag) inline paired_model_matrix compute_helixline_bottom_cap_matrix(const helixline_geometry_data& ag)
{ {
return make_helixline_cap_matrix(ag, 0.0); return make_helixline_cap_matrix(ag, 0.0);
@ -274,6 +276,8 @@ struct extrude_polyline_t final : primitive {
}; };
} }
void update_geometry(const void* new_geometry_ptr, size_t subface_index = 0) override;
/** /**
* @brief descriptor cylinder initialize * @brief descriptor cylinder initialize
* @details initialize * @details initialize
@ -334,6 +338,8 @@ struct extrude_helixline_t final : primitive {
return {surface_type::extrude_helixline_side, surface_type::plane, surface_type::plane}; return {surface_type::extrude_helixline_side, surface_type::plane, surface_type::plane};
} }
void update_geometry(const void* new_geometry_ptr, size_t subface_index = 0) override;
PE_API void initialize_from_descriptor(primitive_data_center_t* dc, const extrude_helixline_descriptor_t& desc); PE_API void initialize_from_descriptor(primitive_data_center_t* dc, const extrude_helixline_descriptor_t& desc);
PE_API void initialize_with_components(primitive_data_center_t* dc, const extrude_helixline_descriptor_t& desc) PE_API void initialize_with_components(primitive_data_center_t* dc, const extrude_helixline_descriptor_t& desc)

7
primitive_process/interface/primitive/simple/sphere.hpp

@ -26,6 +26,13 @@ struct sphere_t final : primitive {
stl_vector_mp<surface_type> get_subface_types() const override { return {surface_type::sphere}; } stl_vector_mp<surface_type> get_subface_types() const override { return {surface_type::sphere}; }
// sphere_t does not support geometry descriptor updates.
void update_geometry(const void * new_geometry_ptr, size_t subface_index = 0) override
{
throw std::invalid_argument("sphere_t::update_geometry: sphere geometry is fully encoded in the model matrix "
"and has no separate descriptor. Use apply_transform() to modify the sphere.");
}
marked_subface_ptr_t<subface> sphere_face{}; marked_subface_ptr_t<subface> sphere_face{};
}; };
} // namespace internal } // namespace internal

2
primitive_process/src/base/primitive.cpp

@ -306,7 +306,7 @@ void primitive::update_geometry(const void* new_geometry_ptr, size_t subface_ind
new_geometry.reserve(subfaces.size()); new_geometry.reserve(subfaces.size());
for (size_t i = 0; i < subfaces.size(); ++i) { for (size_t i = 0; i < subfaces.size(); ++i) {
if (i == subface_index) { if (i == subface_index) {
// 规范化新 descriptor // 规范化新 geometry
const void* canonical_ptr = nullptr; const void* canonical_ptr = nullptr;
switch (subface_types[i]) { switch (subface_types[i]) {

41
primitive_process/src/primitive/simple/extrude.cpp

@ -31,8 +31,8 @@ void extrude_polyline_t::initialize_from_descriptor(primitive_data_center_t* dc,
axis_matrix.local_to_world = geom->axis_to_world; axis_matrix.local_to_world = geom->axis_to_world;
axis_matrix.world_to_local = geom->axis_to_world.inverse(); axis_matrix.world_to_local = geom->axis_to_world.inverse();
paired_model_matrix bottom_matrix = compute_polyline_bottom_cap_matrix(desc.axis); paired_model_matrix bottom_matrix = compute_polyline_bottom_cap_matrix(*geom);
paired_model_matrix top_matrix = compute_polyline_top_cap_matrix(desc.axis); paired_model_matrix top_matrix = compute_polyline_top_cap_matrix(*geom);
std::array<paired_model_matrix, 3> matrix_storage = {axis_matrix, bottom_matrix, top_matrix}; std::array<paired_model_matrix, 3> matrix_storage = {axis_matrix, bottom_matrix, top_matrix};
paired_model_matrix_ptr_t axis_matrix_ptr = make_pointer_wrapper(matrix_storage[0]); paired_model_matrix_ptr_t axis_matrix_ptr = make_pointer_wrapper(matrix_storage[0]);
@ -53,14 +53,10 @@ void extrude_polyline_t::initialize_from_descriptor(primitive_data_center_t* dc,
bottom_cap_desc = descriptor_defaults::unit_plane; bottom_cap_desc = descriptor_defaults::unit_plane;
top_cap_desc = descriptor_defaults::unit_plane; top_cap_desc = descriptor_defaults::unit_plane;
} }
std::cout << "[EXTRUDE_POLYLINE_INIT] Bottom cap AABB min: (" << bottom_cap_desc.local_aabb_min.x << ", "
<< bottom_cap_desc.local_aabb_min.y << ")\n";
std::cout << "[EXTRUDE_POLYLINE_INIT] Bottom cap AABB max: (" << bottom_cap_desc.local_aabb_max.x << ", "
<< bottom_cap_desc.local_aabb_max.y << ")\n";
// 修改initialize调用,传递plane descriptor // 修改initialize调用,传递plane descriptor
initialize({axis_matrix_ptr, bottom_matrix_ptr, top_matrix_ptr}, initialize({axis_matrix_ptr, bottom_matrix_ptr, top_matrix_ptr},
{false, true, false}, // polyline侧面的法向指向内部,因此需要翻转 {false, true, false},
{static_cast<const void*>(geom), {static_cast<const void*>(geom),
nullptr, nullptr,
nullptr}, nullptr},
@ -69,6 +65,19 @@ void extrude_polyline_t::initialize_from_descriptor(primitive_data_center_t* dc,
recompute_aabb(); recompute_aabb();
} }
void extrude_polyline_t::update_geometry(const void* new_geometry_ptr, size_t subface_index)
{
if (subface_index != 0) {
throw std::invalid_argument("extrude_polyline_t::update_geometry: cap planes (index 1 and 2) cannot be "
"updated independently. Their matrices are derived from the axis path. "
"Use replace_profile(), replace_axis(), or initialize_from_descriptor() "
"to rebuild the primitive as a whole.");
}
if (!data_center) { throw std::runtime_error("Primitive not initialized"); }
auto* desc = static_cast<const extrude_polyline_descriptor_t*>(new_geometry_ptr);
initialize_from_descriptor(data_center.raw(), *desc);
}
void extrude_polyline_t::replace_profile(const profile_descriptor_t& new_profile) void extrude_polyline_t::replace_profile(const profile_descriptor_t& new_profile)
{ {
if (!data_center) { throw std::runtime_error("Primitive not initialized"); } if (!data_center) { throw std::runtime_error("Primitive not initialized"); }
@ -125,9 +134,6 @@ void extrude_helixline_t::initialize_from_descriptor(primitive_data_center_t* dc
paired_model_matrix bottom_matrix = compute_helixline_bottom_cap_matrix(geom->axis_geom); paired_model_matrix bottom_matrix = compute_helixline_bottom_cap_matrix(geom->axis_geom);
paired_model_matrix top_matrix = compute_helixline_top_cap_matrix(geom->axis_geom); paired_model_matrix top_matrix = compute_helixline_top_cap_matrix(geom->axis_geom);
std::cout << "[EXTRUDE_HELIXLINE_INIT] Bottom cap matrix(BNTP):\n" << bottom_matrix.local_to_world.matrix() << "\n";
std::cout << "[EXTRUDE_HELIXLINE_INIT] Top cap matrix(BNTP):\n" << top_matrix.local_to_world.matrix() << "\n";
std::array<paired_model_matrix, 3> matrix_storage = {axis_matrix, bottom_matrix, top_matrix}; std::array<paired_model_matrix, 3> matrix_storage = {axis_matrix, bottom_matrix, top_matrix};
paired_model_matrix_ptr_t axis_matrix_ptr = make_pointer_wrapper(matrix_storage[0]); paired_model_matrix_ptr_t axis_matrix_ptr = make_pointer_wrapper(matrix_storage[0]);
paired_model_matrix_ptr_t bottom_matrix_ptr = make_pointer_wrapper(matrix_storage[1]); paired_model_matrix_ptr_t bottom_matrix_ptr = make_pointer_wrapper(matrix_storage[1]);
@ -148,13 +154,26 @@ void extrude_helixline_t::initialize_from_descriptor(primitive_data_center_t* dc
} }
initialize({axis_matrix_ptr, bottom_matrix_ptr, top_matrix_ptr}, initialize({axis_matrix_ptr, bottom_matrix_ptr, top_matrix_ptr},
{false, true, false}, // helixline侧面的法向指向内部,因此需要翻转 {false, true, false},
{static_cast<const void*>(geom), nullptr, nullptr}, {static_cast<const void*>(geom), nullptr, nullptr},
aabb_t{}); aabb_t{});
recompute_aabb(); recompute_aabb();
} }
void extrude_helixline_t::update_geometry(const void* new_geometry_ptr, size_t subface_index)
{
if (subface_index != 0) {
throw std::invalid_argument("extrude_helixline_t::update_geometry: cap planes (index 1 and 2) cannot be "
"updated independently. Their matrices are derived from the helix path. "
"Use replace_profile(), replace_axis(), or initialize_from_descriptor() "
"to rebuild the primitive as a whole.");
}
if (!data_center) { throw std::runtime_error("Primitive not initialized"); }
auto* desc = static_cast<const extrude_helixline_descriptor_t*>(new_geometry_ptr);
initialize_from_descriptor(data_center.raw(), *desc);
}
void extrude_helixline_t::replace_profile(const profile_descriptor_t& new_profile) void extrude_helixline_t::replace_profile(const profile_descriptor_t& new_profile)
{ {
if (!data_center) { throw std::runtime_error("Primitive not initialized"); } if (!data_center) { throw std::runtime_error("Primitive not initialized"); }

Loading…
Cancel
Save