Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/carve/carve-util.cc')
-rw-r--r--extern/carve/carve-util.cc99
1 files changed, 83 insertions, 16 deletions
diff --git a/extern/carve/carve-util.cc b/extern/carve/carve-util.cc
index 0dff1deb750..78997c72e71 100644
--- a/extern/carve/carve-util.cc
+++ b/extern/carve/carve-util.cc
@@ -141,6 +141,11 @@ void carve_getRescaleMinMax(const MeshSet<3> *left,
namespace {
+struct UnionIntersectionContext {
+ VertexAttrsCallback vertex_attr_callback;
+ void *user_data;
+};
+
void copyMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes,
std::vector<MeshSet<3>::mesh_t*> *new_meshes)
{
@@ -154,24 +159,73 @@ void copyMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes,
}
}
-MeshSet<3> *meshSetFromMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes)
+struct NewMeshMapping {
+ std::map<const MeshSet<3>::edge_t*, MeshSet<3>::vertex_t*> orig_edge_vert;
+};
+
+void prepareNewMeshMapping(const std::vector<MeshSet<3>::mesh_t*> &meshes,
+ NewMeshMapping *mapping)
{
- std::vector<MeshSet<3>::mesh_t*> new_meshes;
+ for (size_t m = 0; m < meshes.size(); ++m) {
+ MeshSet<3>::mesh_t *mesh = meshes[m];
+ for (size_t f = 0; f < mesh->faces.size(); ++f) {
+ MeshSet<3>::face_t *face = mesh->faces[f];
+ MeshSet<3>::edge_t *edge = face->edge;
+ do {
+ mapping->orig_edge_vert[edge] = edge->vert;
+ edge = edge->next;
+ } while (edge != face->edge);
+ }
+ }
+}
- copyMeshes(meshes, &new_meshes);
+void runNewMeshSetHooks(UnionIntersectionContext *ctx,
+ NewMeshMapping *mapping,
+ MeshSet<3> *mesh_set)
+{
+ for (size_t m = 0; m < mesh_set->meshes.size(); ++m) {
+ MeshSet<3>::mesh_t *mesh = mesh_set->meshes[m];
+ for (size_t f = 0; f < mesh->faces.size(); ++f) {
+ MeshSet<3>::face_t *face = mesh->faces[f];
+ MeshSet<3>::edge_t *edge = face->edge;
+ do {
+ const MeshSet<3>::vertex_t *orig_vert = mapping->orig_edge_vert[edge];
+ const MeshSet<3>::vertex_t *new_vert = edge->vert;
+ ctx->vertex_attr_callback(orig_vert, new_vert, ctx->user_data);
+ edge = edge->next;
+ } while (edge != face->edge);
+ }
+ }
+}
- return new MeshSet<3>(new_meshes);
+MeshSet<3> *newMeshSetFromMeshesWithAttrs(
+ UnionIntersectionContext *ctx,
+ std::vector<MeshSet<3>::mesh_t*> &meshes)
+{
+ NewMeshMapping mapping;
+ prepareNewMeshMapping(meshes, &mapping);
+ MeshSet<3> *mesh_set = new MeshSet<3>(meshes);
+ runNewMeshSetHooks(ctx, &mapping, mesh_set);
+ return mesh_set;
}
-MeshSet<3> *meshSetFromTwoMeshes(const std::vector<MeshSet<3>::mesh_t*> &left_meshes,
- const std::vector<MeshSet<3>::mesh_t*> &right_meshes)
+
+MeshSet<3> *meshSetFromMeshes(UnionIntersectionContext *ctx,
+ const std::vector<MeshSet<3>::mesh_t*> &meshes)
{
std::vector<MeshSet<3>::mesh_t*> new_meshes;
+ copyMeshes(meshes, &new_meshes);
+ return newMeshSetFromMeshesWithAttrs(ctx, new_meshes);
+}
+MeshSet<3> *meshSetFromTwoMeshes(UnionIntersectionContext *ctx,
+ const std::vector<MeshSet<3>::mesh_t*> &left_meshes,
+ const std::vector<MeshSet<3>::mesh_t*> &right_meshes)
+{
+ std::vector<MeshSet<3>::mesh_t*> new_meshes;
copyMeshes(left_meshes, &new_meshes);
copyMeshes(right_meshes, &new_meshes);
-
- return new MeshSet<3>(new_meshes);
+ return newMeshSetFromMeshesWithAttrs(ctx, new_meshes);
}
bool checkEdgeFaceIntersections_do(Intersections &intersections,
@@ -349,7 +403,8 @@ void getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> *meshes,
}
}
-MeshSet<3> *getIntersectedOperand(std::vector<MeshSet<3>::mesh_t*> *meshes,
+MeshSet<3> *getIntersectedOperand(UnionIntersectionContext *ctx,
+ std::vector<MeshSet<3>::mesh_t*> *meshes,
const MeshSet<3>::aabb_t &otherAABB,
RTreeCache *rtree_cache,
IntersectCache *intersect_cache)
@@ -360,13 +415,14 @@ MeshSet<3> *getIntersectedOperand(std::vector<MeshSet<3>::mesh_t*> *meshes,
if (operandMeshes.size() == 0)
return NULL;
- return meshSetFromMeshes(operandMeshes);
+ return meshSetFromMeshes(ctx, operandMeshes);
}
MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
MeshSet<3> *poly,
const MeshSet<3> *other_poly,
const MeshSet<3>::aabb_t &otherAABB,
+ VertexAttrsCallback vertex_attr_callback,
UnionIntersectionsCallback callback,
void *user_data)
{
@@ -380,7 +436,12 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
RTreeCache rtree_cache;
IntersectCache intersect_cache;
- MeshSet<3> *left = getIntersectedOperand(&orig_meshes,
+ UnionIntersectionContext ctx;
+ ctx.vertex_attr_callback = vertex_attr_callback;
+ ctx.user_data = user_data;
+
+ MeshSet<3> *left = getIntersectedOperand(&ctx,
+ &orig_meshes,
otherAABB,
&rtree_cache,
&intersect_cache);
@@ -391,7 +452,8 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
}
while (orig_meshes.size()) {
- MeshSet<3> *right = getIntersectedOperand(&orig_meshes,
+ MeshSet<3> *right = getIntersectedOperand(&ctx,
+ &orig_meshes,
otherAABB,
&rtree_cache,
&intersect_cache);
@@ -422,7 +484,9 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
catch (carve::exception e) {
std::cerr << "CSG failed, exception " << e.str() << std::endl;
- MeshSet<3> *result = meshSetFromTwoMeshes(left->meshes, right->meshes);
+ MeshSet<3> *result = meshSetFromTwoMeshes(&ctx,
+ left->meshes,
+ right->meshes);
callback(result, other_poly, user_data);
@@ -448,7 +512,9 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
// Append all meshes which doesn't have intersection with another operand as-is.
if (orig_meshes.size()) {
- MeshSet<3> *result = meshSetFromTwoMeshes(left->meshes, orig_meshes);
+ MeshSet<3> *result = meshSetFromTwoMeshes(&ctx,
+ left->meshes,
+ orig_meshes);
delete left;
left = result;
@@ -464,6 +530,7 @@ MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
void carve_unionIntersections(carve::csg::CSG *csg,
MeshSet<3> **left_r,
MeshSet<3> **right_r,
+ VertexAttrsCallback vertex_attr_callback,
UnionIntersectionsCallback callback,
void *user_data)
{
@@ -477,9 +544,9 @@ void carve_unionIntersections(carve::csg::CSG *csg,
MeshSet<3>::aabb_t rightAABB = right->getAABB();;
left = unionIntersectingMeshes(csg, left, right, rightAABB,
- callback, user_data);
+ vertex_attr_callback, callback, user_data);
right = unionIntersectingMeshes(csg, right, left, leftAABB,
- callback, user_data);
+ vertex_attr_callback, callback, user_data);
if (left != *left_r) {
delete *left_r;