diff --git a/src/meshlabplugins/filter_dirt/filter_dirt.cpp b/src/meshlabplugins/filter_dirt/filter_dirt.cpp index 562ddb172..6ede064b5 100644 --- a/src/meshlabplugins/filter_dirt/filter_dirt.cpp +++ b/src/meshlabplugins/filter_dirt/filter_dirt.cpp @@ -1,45 +1,44 @@ -/**************************************************************************** -* MeshLab o o * -* An extendible mesh processor o o * -* _ O _ * -* Copyright(C) 2005, 2006 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ +/***************************************************************************** + * MeshLab o o * + * An extendible mesh processor o o * + * _ O _ * + * Copyright(C) 2005-2021 \/)\/ * + * Visual Computing Lab /\/| * + * ISTI - Italian National Research Council | * + * \ * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * + * for more details. * + * * + ****************************************************************************/ #include "filter_dirt.h" -#include "particle.h" #include "dirt_utils.h" +#include "particle.h" -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -49,12 +48,9 @@ using namespace tri; FilterDirt::FilterDirt() { - typeList = { - FP_DIRT, - FP_CLOUD_MOVEMENT - }; + typeList = {FP_DIRT, FP_CLOUD_MOVEMENT}; - for(ActionIDType tt: types()) + for (ActionIDType tt : types()) actionList.push_back(new QAction(filterName(tt), this)); } @@ -66,17 +62,17 @@ QString FilterDirt::pluginName() const QString FilterDirt::filterName(ActionIDType filterId) const { switch (filterId) { - case FP_DIRT:{ + case FP_DIRT: { return QString("Dust Accumulation"); break; } - case FP_CLOUD_MOVEMENT: - { + case FP_CLOUD_MOVEMENT: { return QString("Points Cloud Movement"); break; } - default:{ - assert(0); return QString("error"); + default: { + assert(0); + return QString("error"); break; } } @@ -85,162 +81,214 @@ QString FilterDirt::filterName(ActionIDType filterId) const QString FilterDirt::filterInfo(ActionIDType filterId) const { switch (filterId) { - case FP_DIRT:{ - return QString("Simulate dust accumulation over the mesh generating a cloud of points lying on the current mesh"); + case FP_DIRT: + return QString( + "Simulate dust accumulation over the mesh generating a cloud of points lying on the " + "current mesh"); break; - } - case FP_CLOUD_MOVEMENT:{ - return QString("Simulate the movement of a points cloud over a mesh"); + case FP_CLOUD_MOVEMENT: + return QString("Simulate the movement of a point cloud over a mesh"); break; - } default: - assert(0); return QString("error"); + assert(0); + return QString("error"); break; } } -RichParameterList FilterDirt::initParameterList(const QAction* filter, const MeshDocument & /*md*/) +RichParameterList FilterDirt::initParameterList(const QAction* filter, const MeshDocument& md) { RichParameterList par; - switch(ID(filter)){ - - case FP_DIRT:{ - par.addParam(RichDirection("dust_dir", Point3m(0, 1, 0), "Direction", "Direction of the dust source")); - par.addParam(RichInt("nparticles", 3, "max particles x face", "Max Number of Dust Particles to Generate Per Face")); - par.addParam(RichFloat("slippiness", 1.0f, "s", "The surface slippines(large s means less sticky)")); - par.addParam(RichFloat("adhesion", 0.2f, "k", "Factor to model the general adhesion")); - par.addParam(RichBool("draw_texture", false, "Draw Dust", "create a new texture saved in dirt_texture.png")); - // par.addParam(RichBool("colorize_mesh",false,"Map to Color","Color the mesh with colors based on the movement of the particle")); - break; + const MeshModel* pc = md.mm(); + const MeshModel* target = md.mm(); + if (md.mm()->cm.FN() == 0) { // point cloud looks ok + // looking for the target mesh different that the current one + for (const MeshModel& t : md.meshIterator()) { + if (&t != md.mm() && t.cm.FN() > 0) { + target = &t; + break; + } + } } - case FP_CLOUD_MOVEMENT:{ + else { // target mesh looks ok + // looking for the point cloud mesh different that the current one + for (const MeshModel& t : md.meshIterator()) { + if (&t != md.mm() && t.cm.FN() == 0) { + pc = &t; + break; + } + } + } + + switch (ID(filter)) { + case FP_DIRT: + par.addParam(RichDirection( + "dust_dir", Point3m(0, 1, 0), "Direction", "Direction of the dust source")); + par.addParam(RichInt( + "nparticles", + 3, + "max particles x face", + "Max Number of Dust Particles to Generate Per Face")); + par.addParam( + RichFloat("slippiness", 1.0f, "s", "The surface slippines(large s means less sticky)")); + par.addParam(RichFloat("adhesion", 0.2f, "k", "Factor to model the general adhesion")); + par.addParam(RichBool( + "draw_texture", false, "Draw Dust", "create a new texture saved in dirt_texture.png")); + // par.addParam(RichBool("colorize_mesh",false,"Map to Color","Color the mesh with colors + // based on the movement of the particle")); + break; + case FP_CLOUD_MOVEMENT: + par.addParam(RichMesh( + "point_cloud", + pc->id(), + &md, + "Point cloud", + "The point cloud that will be moved over the target mesh.")); + par.addParam(RichMesh( + "target_mesh", + target->id(), + &md, + "Target mesh", + "Target mesh on which the point cloud will be moved.")); par.addParam(RichDirection("gravity_dir", Point3m(0, -1, 0), "g", "Direction of gravity")); - par.addParam(RichDirection("force_dir", Point3m(0, 0, 0), "force", "Direction of the force acting on the points cloud")); + par.addParam(RichDirection( + "force_dir", + Point3m(0, 0, 0), + "force", + "Direction of the force acting on the points cloud")); par.addParam(RichInt("steps", 1, "s", "Simulation Steps")); - par.addParam(RichDynamicFloat("adhesion", 1.0f, 0.0f, 1.0f, "adhesion", "Factor to model the general adhesion.")); + par.addParam(RichDynamicFloat( + "adhesion", 1.0f, 0.0f, 1.0f, "adhesion", "Factor to model the general adhesion.")); par.addParam(RichFloat("velocity", 0, "v", "Initial velocity of the particle")); par.addParam(RichFloat("mass", 1, "m", "Mass of the particle")); - par.addParam(RichBool("colorize_mesh", false, "Map to Color", "Color the mesh with colors based on the movement of the particle")); + par.addParam(RichBool( + "colorize_mesh", + false, + "Map to Color", + "Color the mesh with colors based on the movement of the particle")); break; - } - default:{ - break; - } + default: break; } return par; } -int FilterDirt::getRequirements(const QAction * /*action*/) +int FilterDirt::getRequirements(const QAction* /*action*/) { - return MeshModel::MM_FACEFACETOPO | MeshModel::MM_VERTCOLOR |MeshModel::MM_FACECOLOR; + return MeshModel::MM_FACEFACETOPO | MeshModel::MM_VERTCOLOR | MeshModel::MM_FACECOLOR; } -std::map FilterDirt::applyFilter(const QAction *filter, const RichParameterList &par, MeshDocument &md, unsigned int& /*postConditionMask*/, vcg::CallBackPos *cb){ - switch(ID(filter)){ - - case FP_DIRT:{ +std::map FilterDirt::applyFilter( + const QAction* filter, + const RichParameterList& par, + MeshDocument& md, + unsigned int& /*postConditionMask*/, + vcg::CallBackPos* cb) +{ + switch (ID(filter)) { + case FP_DIRT: { /*Get Parameters*/ - Point3m dir=par.getPoint3m("dust_dir"); - Scalarm s=par.getFloat("slippiness"); - Scalarm k=par.getFloat("adhesion"); - bool draw=par.getBool("draw_texture"); - //bool colorize=par.getBool("colorize_mesh"); - int n_p=par.getInt("nparticles"); + Point3m dir = par.getPoint3m("dust_dir"); + Scalarm s = par.getFloat("slippiness"); + Scalarm k = par.getFloat("adhesion"); + bool draw = par.getBool("draw_texture"); + // bool colorize=par.getBool("colorize_mesh"); + int n_p = par.getInt("nparticles"); - MeshModel* currMM=md.mm(); + MeshModel* currMM = md.mm(); - if (currMM->cm.fn==0) { - throw MLException("This filter requires a mesh with some faces, it does not work on PointSet"); + if (currMM->cm.fn == 0) { + throw MLException( + "This filter requires a mesh with some faces, it does not work on PointSet"); } - if(draw && !tri::HasPerWedgeTexCoord(currMM->cm)){ + if (draw && !tri::HasPerWedgeTexCoord(currMM->cm)) { throw MLException("Current Mesh does not have per Wedge Tex Coordinates"); } vector dust_points; prepareMesh(currMM); - if(cb) (*cb)(10,"Computing Dust Amount..."); + if (cb) + (*cb)(10, "Computing Dust Amount..."); - ComputeNormalDustAmount(currMM,dir,k,s); - if(cb) (*cb)(30,"Computing Mesh Exposure..."); + ComputeNormalDustAmount(currMM, dir, k, s); + if (cb) + (*cb)(30, "Computing Mesh Exposure..."); - ComputeSurfaceExposure(currMM,1,1); + ComputeSurfaceExposure(currMM, 1, 1); - if(cb) (*cb)(50,"Generating Particles..."); + if (cb) + (*cb)(50, "Generating Particles..."); - GenerateParticles(currMM, dust_points,/*dust_particles,*/n_p, 0.6f); - MeshModel* dmm=md.addNewMesh("","dust_mesh",true); + GenerateParticles(currMM, dust_points, /*dust_particles,*/ n_p, 0.6f); + MeshModel* dmm = md.addNewMesh("", "dust_mesh", true); dmm->cm.Clear(); - tri::Allocator::AddVertices(dmm->cm,dust_points.size()); - CMeshO::VertexIterator vi; - vector::iterator dvi=dust_points.begin(); - if(cb) (*cb)(70,"Creating cloud Mesh..."); - for(vi=dmm->cm.vert.begin();vi!=dmm->cm.vert.end();++vi){ - vi->P()=(*dvi); + tri::Allocator::AddVertices(dmm->cm, dust_points.size()); + CMeshO::VertexIterator vi; + vector::iterator dvi = dust_points.begin(); + if (cb) + (*cb)(70, "Creating cloud Mesh..."); + for (vi = dmm->cm.vert.begin(); vi != dmm->cm.vert.end(); ++vi) { + vi->P() = (*dvi); ++dvi; } - if(draw) DrawDust(currMM,dmm); - //if(colorize) ColorizeMesh(currMM); - + if (draw) + DrawDust(currMM, dmm); + // if(colorize) ColorizeMesh(currMM); break; } - case FP_CLOUD_MOVEMENT:{ - if(md.meshNumber()!=2){ - throw MLException("This filter requires two mesh"); + case FP_CLOUD_MOVEMENT: { + MeshModel* base_mesh = md.getMesh(par.getMeshId("target_mesh")); + if (base_mesh->cm.fn == 0) { + throw MLException("The filter requires that the target mesh has some faces"); } - MeshModel* base_mesh=md.getMesh(0); - if(base_mesh->cm.fn==0){ - throw MLException("The filter requires that the first mesh has some faces"); + MeshModel* cloud_mesh = md.getMesh(par.getMeshId("point_cloud")); + if (cloud_mesh->cm.fn != 0) { + throw MLException("The filter requires that the point cloud has zero faces"); } - MeshModel* cloud_mesh=md.getMesh(1); - if(cloud_mesh->cm.fn!=0){ - throw MLException("The filter requires that the second mesh is a Point Set"); - } - - //Get Parameters - Point3m dir=par.getPoint3m("force_dir"); - Point3m g=par.getPoint3m("gravity_dir"); - Scalarm adhesion =par.getDynamicFloat("adhesion"); - Scalarm l=base_mesh->cm.bbox.Diag()*0.01; //mm()->cm.bbox.Diag(); - Scalarm v=par.getFloat("velocity"); - Scalarm m=par.getFloat("mass"); - int s=par.getInt("steps"); - bool colorize=par.getBool("colorize_mesh"); - if(!HasPerVertexAttribute(cloud_mesh->cm,"ParticleInfo")){ + // Get Parameters + Point3m dir = par.getPoint3m("force_dir"); + Point3m g = par.getPoint3m("gravity_dir"); + Scalarm adhesion = par.getDynamicFloat("adhesion"); + Scalarm l = base_mesh->cm.bbox.Diag() * 0.01; // mm()->cm.bbox.Diag(); + Scalarm v = par.getFloat("velocity"); + Scalarm m = par.getFloat("mass"); + int s = par.getInt("steps"); + bool colorize = par.getBool("colorize_mesh"); + if (!HasPerVertexAttribute(cloud_mesh->cm, "ParticleInfo")) { prepareMesh(base_mesh); - //Associate every point to a mesh and a Particle to every point - associateParticles(base_mesh,cloud_mesh,m,v,g); + // Associate every point to a mesh and a Particle to every point + associateParticles(base_mesh, cloud_mesh, m, v, g); } - //Move Cloud Mesh - float frac=100/s; - for(int i=0;i(); -}//End applyFilter +} // End applyFilter -int FilterDirt::postCondition(const QAction *a) const +int FilterDirt::postCondition(const QAction* a) const { - switch (ID(a)){ + switch (ID(a)) { case FP_DIRT: return MeshModel::MM_ALL; case FP_CLOUD_MOVEMENT: return MeshModel::MM_ALL; default: assert(0); @@ -248,12 +296,12 @@ int FilterDirt::postCondition(const QAction *a) const return MeshModel::MM_ALL; } -FilterPlugin::FilterClass FilterDirt::getClass(const QAction *filter) const +FilterPlugin::FilterClass FilterDirt::getClass(const QAction* filter) const { - switch (ID(filter)) { - case FP_DIRT:return FilterPlugin::Sampling; - case FP_CLOUD_MOVEMENT:return FilterPlugin::Remeshing; - default:assert(0); + switch (ID(filter)) { + case FP_DIRT: return FilterPlugin::Sampling; + case FP_CLOUD_MOVEMENT: return FilterPlugin::Remeshing; + default: assert(0); } return FilterPlugin::Generic; } diff --git a/src/meshlabplugins/filter_dirt/filter_dirt.h b/src/meshlabplugins/filter_dirt/filter_dirt.h index d3a4467af..620404ead 100644 --- a/src/meshlabplugins/filter_dirt/filter_dirt.h +++ b/src/meshlabplugins/filter_dirt/filter_dirt.h @@ -1,75 +1,66 @@ -/**************************************************************************** -* MeshLab o o * -* A versatile mesh processing toolbox o o * -* _ O _ * -* Copyright(C) 2007 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ +/***************************************************************************** + * MeshLab o o * + * A versatile mesh processing toolbox o o * + * _ O _ * + * Copyright(C) 2005-2021 \/)\/ * + * Visual Computing Lab /\/| * + * ISTI - Italian National Research Council | * + * \ * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * + * for more details. * + * * + ****************************************************************************/ #ifndef FILTERDIRTPLUGIN_H #define FILTERDIRTPLUGIN_H #include -#include #include +#include #include -#include -#include -//#include "muParser.h" +#include +#include using namespace vcg; -//using namespace mu; - class FilterDirt : public QObject, public FilterPlugin { Q_OBJECT MESHLAB_PLUGIN_IID_EXPORTER(FILTER_PLUGIN_IID) Q_INTERFACES(FilterPlugin) -protected: - double x,y,z,nx,ny,nz,r,g,b,q,rad; - //double x0,y0,z0,x1,y1,z1,x2,y2,z2,nx0,ny0,nz0,nx1,ny1,nz1,nx2,ny2,nz2,r0,g0,b0,r1,g1,b1,r2,g2,b2,q0,q1,q2; - double v,f,v0i,v1i,v2i; - std::vector v_attrNames; - std::vector v_attrValue; - //std::vector f_attrNames; - //std:: vector f_attrValue; - std::vector > vhandlers; - //std::vector > fhandlers; public: - enum {FP_DIRT,FP_CLOUD_MOVEMENT} ; + enum { FP_DIRT, FP_CLOUD_MOVEMENT }; FilterDirt(); - ~FilterDirt(){}; + ~FilterDirt() {}; - QString pluginName() const; + QString pluginName() const; virtual QString filterName(ActionIDType filter) const; virtual QString filterInfo(ActionIDType filter) const; - virtual int getRequirements(const QAction*); - virtual bool autoDialog(QAction *) {return true;} + virtual int getRequirements(const QAction*); + virtual bool autoDialog(QAction*) { return true; } // virtual void initParameterSet(QAction* filter,MeshModel &,RichParameterSet &){}; - RichParameterList initParameterList(const QAction*, const MeshDocument &/*m*/); - std::map applyFilter(const QAction* action, const RichParameterList & /*parent*/, MeshDocument &md, unsigned int& postConditionMask, vcg::CallBackPos * cb); - virtual int postCondition(const QAction*) const; - virtual FilterClass getClass (const QAction *) const; - FilterArity filterArity(const QAction*) const {return SINGLE_MESH;} + RichParameterList initParameterList(const QAction*, const MeshDocument& /*m*/); + std::map applyFilter( + const QAction* action, + const RichParameterList& /*parent*/, + MeshDocument& md, + unsigned int& postConditionMask, + vcg::CallBackPos* cb); + virtual int postCondition(const QAction*) const; + virtual FilterClass getClass(const QAction*) const; + FilterArity filterArity(const QAction*) const { return SINGLE_MESH; } }; - #endif diff --git a/src/meshlabplugins/filter_mesh_booleans/filter_mesh_booleans.cpp b/src/meshlabplugins/filter_mesh_booleans/filter_mesh_booleans.cpp index 2bcdbb065..27cf3054f 100644 --- a/src/meshlabplugins/filter_mesh_booleans/filter_mesh_booleans.cpp +++ b/src/meshlabplugins/filter_mesh_booleans/filter_mesh_booleans.cpp @@ -1,25 +1,25 @@ -/**************************************************************************** -* MeshLab o o * -* A versatile mesh processing toolbox o o * -* _ O _ * -* Copyright(C) 2005-2021 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ +/***************************************************************************** + * MeshLab o o * + * A versatile mesh processing toolbox o o * + * _ O _ * + * Copyright(C) 2005-2021 \/)\/ * + * Visual Computing Lab /\/| * + * ISTI - Italian National Research Council | * + * \ * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * + * for more details. * + * * + ****************************************************************************/ #include "filter_mesh_booleans.h" @@ -32,17 +32,14 @@ * Constructor usually performs only two simple tasks of filling the two lists * - typeList: with all the possible id of the filtering actions * - actionList with the corresponding actions. - * If you want to add icons to your filtering actions you can do here by construction the QActions accordingly + * If you want to add icons to your filtering actions you can do here by construction the QActions + * accordingly */ FilterMeshBooleans::FilterMeshBooleans() { - typeList = { - MESH_INTERSECTION, - MESH_UNION, - MESH_DIFFERENCE, - MESH_XOR}; + typeList = {MESH_INTERSECTION, MESH_UNION, MESH_DIFFERENCE, MESH_XOR}; - for(const ActionIDType& tt : typeList) + for (const ActionIDType& tt : typeList) actionList.push_back(new QAction(filterName(tt), this)); } @@ -64,22 +61,15 @@ QString FilterMeshBooleans::vendor() const */ QString FilterMeshBooleans::filterName(ActionIDType filterId) const { - switch(filterId) { - case MESH_INTERSECTION : - return "Mesh Boolean: Intersection"; - case MESH_UNION: - return "Mesh Boolean: Union"; - case MESH_DIFFERENCE: - return "Mesh Boolean: Difference"; - case MESH_XOR: - return "Mesh Boolean: Symmetric Difference (XOR)"; - default : - assert(0); - return ""; + switch (filterId) { + case MESH_INTERSECTION: return "Mesh Boolean: Intersection"; + case MESH_UNION: return "Mesh Boolean: Union"; + case MESH_DIFFERENCE: return "Mesh Boolean: Difference"; + case MESH_XOR: return "Mesh Boolean: Symmetric Difference (XOR)"; + default: assert(0); return ""; } } - /** * @brief // Info() must return the longer string describing each filtering action * (this string is used in the About plugin dialog) @@ -95,18 +85,12 @@ QString FilterMeshBooleans::filterInfo(ActionIDType filterId) const "The implementation refers to the following paper:
" "Qingnan Zhou, Eitan Grinspun, Denis Zorin, Alec Jacobson,
" "\"Mesh Arrangements for Solid Geometry\"
"; - switch(filterId) { - case MESH_INTERSECTION : - return description.arg("intersection"); - case MESH_UNION: - return description.arg("union"); - case MESH_DIFFERENCE: - return description.arg("difference"); - case MESH_XOR: - return description.arg("symmetric difference (XOR)"); - default : - assert(0); - return "Unknown Filter"; + switch (filterId) { + case MESH_INTERSECTION: return description.arg("intersection"); + case MESH_UNION: return description.arg("union"); + case MESH_DIFFERENCE: return description.arg("difference"); + case MESH_XOR: return description.arg("symmetric difference (XOR)"); + default: assert(0); return "Unknown Filter"; } } @@ -117,17 +101,16 @@ QString FilterMeshBooleans::filterInfo(ActionIDType filterId) const * @param a: the action of the filter * @return the class od the filter */ -FilterMeshBooleans::FilterClass FilterMeshBooleans::getClass(const QAction *a) const +FilterMeshBooleans::FilterClass FilterMeshBooleans::getClass(const QAction* a) const { - switch(ID(a)) { - case MESH_INTERSECTION : + switch (ID(a)) { + case MESH_INTERSECTION: case MESH_UNION: case MESH_DIFFERENCE: case MESH_XOR: - return FilterPlugin::FilterClass(FilterPlugin::FilterClass(FilterPlugin::Layer + FilterPlugin::Remeshing)); - default : - assert(0); - return FilterPlugin::Generic; + return FilterPlugin::FilterClass( + FilterPlugin::FilterClass(FilterPlugin::Layer + FilterPlugin::Remeshing)); + default: assert(0); return FilterPlugin::Generic; } } @@ -144,7 +127,7 @@ FilterPlugin::FilterArity FilterMeshBooleans::filterArity(const QAction*) const * @brief FilterSamplePlugin::getPreConditions * @return */ -//int FilterMeshBooleans::getPreConditions(const QAction*) const +// int FilterMeshBooleans::getPreConditions(const QAction*) const //{ // return MeshModel::MM_NONE; //} @@ -153,37 +136,36 @@ FilterPlugin::FilterArity FilterMeshBooleans::filterArity(const QAction*) const * @brief FilterSamplePlugin::postCondition * @return */ -//int FilterMeshBooleans::postCondition(const QAction*) const +// int FilterMeshBooleans::postCondition(const QAction*) const //{ // return MeshModel::MM_VERTCOORD | MeshModel::MM_FACENORMAL | MeshModel::MM_VERTNORMAL; //} /** - * @brief This function define the needed parameters for each filter. Return true if the filter has some parameters - * it is called every time, so you can set the default value of parameters according to the mesh - * For each parameter you need to define, + * @brief This function define the needed parameters for each filter. Return true if the filter has + * some parameters it is called every time, so you can set the default value of parameters according + * to the mesh For each parameter you need to define, * - the name of the parameter, * - the default value * - the string shown in the dialog - * - a possibly long string describing the meaning of that parameter (shown as a popup help in the dialog) + * - a possibly long string describing the meaning of that parameter (shown as a popup help in the + * dialog) * @param action * @param m * @param parlst */ -RichParameterList FilterMeshBooleans::initParameterList( - const QAction *action, - const MeshDocument& md) +RichParameterList +FilterMeshBooleans::initParameterList(const QAction* action, const MeshDocument& md) { RichParameterList parlst; - switch(ID(action)) { - case MESH_INTERSECTION : + switch (ID(action)) { + case MESH_INTERSECTION: case MESH_UNION: case MESH_DIFFERENCE: - case MESH_XOR: - { - const MeshModel *target = md.mm(); - //looking for a second mesh different that the current one - for (const MeshModel& t : md.meshIterator()){ + case MESH_XOR: { + const MeshModel* target = md.mm(); + // looking for a second mesh different that the current one + for (const MeshModel& t : md.meshIterator()) { if (&t != md.mm()) { target = &t; break; @@ -191,35 +173,47 @@ RichParameterList FilterMeshBooleans::initParameterList( } parlst.addParam(RichMesh( - "first_mesh", md.mm()->id(), &md, "First Mesh", - "The first operand of the boolean operation")); + "first_mesh", + md.mm()->id(), + &md, + "First Mesh", + "The first operand of the boolean operation")); parlst.addParam(RichMesh( - "second_mesh", target->id(), &md, "Second Mesh", - "The second operand of the boolean operation")); + "second_mesh", + target->id(), + &md, + "Second Mesh", + "The second operand of the boolean operation")); parlst.addParam(RichBool( - "transfer_face_color", false, - "Transfer face color", "Save the color of the birth face to the faces of resulting mesh.")); + "transfer_face_color", + false, + "Transfer face color", + "Save the color of the birth face to the faces of resulting mesh.")); parlst.addParam(RichBool( - "transfer_face_quality", false, - "Transfer face quality", "Save the quality of the birth face to the faces of resulting mesh.")); + "transfer_face_quality", + false, + "Transfer face quality", + "Save the quality of the birth face to the faces of resulting mesh.")); parlst.addParam(RichBool( - "transfer_vert_color", false, - "Transfer vertex color", - "Save the color of the birth vertex to the faces of resulting mesh. For newly created vertices, " - "a simple average of the neighbours is computed.")); + "transfer_vert_color", + false, + "Transfer vertex color", + "Save the color of the birth vertex to the faces of resulting mesh. For newly created " + "vertices, " + "a simple average of the neighbours is computed.")); parlst.addParam(RichBool( - "transfer_vert_quality", false, - "Transfer vertex quality", - "Save the quality of the birth vertex to the faces of resulting mesh. For newly created vertices, " - "a simple average of the neighbours is computed.")); - } - break; - default : - assert(0); + "transfer_vert_quality", + false, + "Transfer vertex quality", + "Save the quality of the birth vertex to the faces of resulting mesh. For newly " + "created vertices, " + "a simple average of the neighbours is computed.")); + } break; + default: assert(0); } return parlst; } @@ -233,65 +227,63 @@ RichParameterList FilterMeshBooleans::initParameterList( * @return true if the filter has been applied correctly, false otherwise */ std::map FilterMeshBooleans::applyFilter( - const QAction * action, - const RichParameterList & par, - MeshDocument &md, - unsigned int& /*postConditionMask*/, - vcg::CallBackPos *) + const QAction* action, + const RichParameterList& par, + MeshDocument& md, + unsigned int& /*postConditionMask*/, + vcg::CallBackPos*) { bool transfFaceQuality = par.getBool("transfer_face_quality"); - bool transfFaceColor = par.getBool("transfer_face_color"); + bool transfFaceColor = par.getBool("transfer_face_color"); bool transfVertQuality = par.getBool("transfer_vert_quality"); - bool transfVertColor = par.getBool("transfer_vert_color"); + bool transfVertColor = par.getBool("transfer_vert_color"); - - switch(ID(action)) { - case MESH_INTERSECTION : + switch (ID(action)) { + case MESH_INTERSECTION: booleanOperation( - md, - *md.getMesh(par.getMeshId("first_mesh")), - *md.getMesh(par.getMeshId("second_mesh")), - igl::MESH_BOOLEAN_TYPE_INTERSECT, - transfFaceQuality, - transfFaceColor, - transfVertQuality, - transfVertColor); + md, + *md.getMesh(par.getMeshId("first_mesh")), + *md.getMesh(par.getMeshId("second_mesh")), + igl::MESH_BOOLEAN_TYPE_INTERSECT, + transfFaceQuality, + transfFaceColor, + transfVertQuality, + transfVertColor); break; case MESH_UNION: booleanOperation( - md, - *md.getMesh(par.getMeshId("first_mesh")), - *md.getMesh(par.getMeshId("second_mesh")), - igl::MESH_BOOLEAN_TYPE_UNION, - transfFaceQuality, - transfFaceColor, - transfVertQuality, - transfVertColor); + md, + *md.getMesh(par.getMeshId("first_mesh")), + *md.getMesh(par.getMeshId("second_mesh")), + igl::MESH_BOOLEAN_TYPE_UNION, + transfFaceQuality, + transfFaceColor, + transfVertQuality, + transfVertColor); break; case MESH_DIFFERENCE: booleanOperation( - md, - *md.getMesh(par.getMeshId("first_mesh")), - *md.getMesh(par.getMeshId("second_mesh")), - igl::MESH_BOOLEAN_TYPE_MINUS, - transfFaceQuality, - transfFaceColor, - transfVertQuality, - transfVertColor); + md, + *md.getMesh(par.getMeshId("first_mesh")), + *md.getMesh(par.getMeshId("second_mesh")), + igl::MESH_BOOLEAN_TYPE_MINUS, + transfFaceQuality, + transfFaceColor, + transfVertQuality, + transfVertColor); break; case MESH_XOR: booleanOperation( - md, - *md.getMesh(par.getMeshId("first_mesh")), - *md.getMesh(par.getMeshId("second_mesh")), - igl::MESH_BOOLEAN_TYPE_XOR, - transfFaceQuality, - transfFaceColor, - transfVertQuality, - transfVertColor); + md, + *md.getMesh(par.getMeshId("first_mesh")), + *md.getMesh(par.getMeshId("second_mesh")), + igl::MESH_BOOLEAN_TYPE_XOR, + transfFaceQuality, + transfFaceColor, + transfVertQuality, + transfVertColor); break; - default : - wrongActionCalled(action); + default: wrongActionCalled(action); } return std::map(); } @@ -307,56 +299,51 @@ std::map FilterMeshBooleans::applyFilter( * @param transfColor: if true, face color will be transferred in the res mesh */ void FilterMeshBooleans::booleanOperation( - MeshDocument& md, - const MeshModel& m1, - const MeshModel& m2, - int op, - bool transfFaceQuality, - bool transfFaceColor, - bool transfVertQuality, - bool transfVertColor) + MeshDocument& md, + const MeshModel& m1, + const MeshModel& m2, + int op, + bool transfFaceQuality, + bool transfFaceColor, + bool transfVertQuality, + bool transfVertColor) { QString name; switch (op) { - case igl::MESH_BOOLEAN_TYPE_INTERSECT: - name = "intersection"; - break; - case igl::MESH_BOOLEAN_TYPE_MINUS: - name = "difference"; - break; - case igl::MESH_BOOLEAN_TYPE_XOR: - name = "xor"; - break; - case igl::MESH_BOOLEAN_TYPE_UNION: - name = "union"; - break; + case igl::MESH_BOOLEAN_TYPE_INTERSECT: name = "intersection"; break; + case igl::MESH_BOOLEAN_TYPE_MINUS: name = "difference"; break; + case igl::MESH_BOOLEAN_TYPE_XOR: name = "xor"; break; + case igl::MESH_BOOLEAN_TYPE_UNION: name = "union"; break; default: - throw MLException("Boolean Operation not found! Please report this issue on https://github.com/cnr-isti-vclab/meshlab/issues"); + throw MLException( + "Boolean Operation not found! Please report this issue on " + "https://github.com/cnr-isti-vclab/meshlab/issues"); } - //vcg to eigen meshes - EigenMatrixX3m V1 = meshlab::vertexMatrix(m1.cm); + // vcg to eigen meshes + EigenMatrixX3m V1 = meshlab::vertexMatrix(m1.cm); Eigen::MatrixX3i F1 = meshlab::faceMatrix(m1.cm); - EigenMatrixX3m V2 = meshlab::vertexMatrix(m2.cm); + EigenMatrixX3m V2 = meshlab::vertexMatrix(m2.cm); Eigen::MatrixX3i F2 = meshlab::faceMatrix(m2.cm); - EigenMatrixX3m VR; + EigenMatrixX3m VR; Eigen::MatrixX3i FR; - Eigen::VectorXi indices; //mapping indices for birth faces + Eigen::VectorXi indices; // mapping indices for birth faces - bool result = igl::copyleft::cgal::mesh_boolean(V1, F1, V2, F2, (igl::MeshBooleanType)op, VR, FR, indices); + bool result = igl::copyleft::cgal::mesh_boolean( + V1, F1, V2, F2, (igl::MeshBooleanType) op, VR, FR, indices); - if (!result){ + if (!result) { throw MLException( "Mesh inputs must induce a piecewise constant winding number field.
" "Make sure that both the input mesh are watertight (closed)."); } else { - //everything ok, create new mesh into md + // everything ok, create new mesh into md MeshModel* mesh = md.addNewMesh("", name); - mesh->cm = meshlab::meshFromMatrices(VR, FR); + mesh->cm = meshlab::meshFromMatrices(VR, FR); - //if transfer option enabled + // if transfer option enabled if (transfFaceColor || transfFaceQuality) transferFaceAttributes(*mesh, indices, m1, m2, transfFaceQuality, transfFaceColor); if (transfVertColor || transfVertQuality) @@ -381,16 +368,16 @@ void FilterMeshBooleans::booleanOperation( * @param color: if true, face color will be transferred */ void FilterMeshBooleans::transferFaceAttributes( - MeshModel& res, - const Eigen::VectorXi& faceIndices, - const MeshModel& m1, - const MeshModel& m2, - bool quality, - bool color) + MeshModel& res, + const Eigen::VectorXi& faceIndices, + const MeshModel& m1, + const MeshModel& m2, + bool quality, + bool color) { - //checking if m1 and m2 have quality and color + // checking if m1 and m2 have quality and color bool m1HasQuality = true, m1HasColor = true, m2HasQuality = true, m2HasColor = true; - if (quality){ + if (quality) { res.updateDataMask(MeshModel::MM_FACEQUALITY); if (!m1.hasDataMask(MeshModel::MM_FACEQUALITY)) m1HasQuality = false; @@ -405,20 +392,20 @@ void FilterMeshBooleans::transferFaceAttributes( m2HasColor = false; } - //for each index in the birth faces vector - for (unsigned int i = 0; i < faceIndices.size(); ++i){ - bool fromM1 = true; + // for each index in the birth faces vector + for (unsigned int i = 0; i < faceIndices.size(); ++i) { + bool fromM1 = true; unsigned int mIndex = faceIndices[i]; - //if the index is >= FN of m1, it means that the index is of m2 - if (faceIndices[i] >= m1.cm.FN()){ + // if the index is >= FN of m1, it means that the index is of m2 + if (faceIndices[i] >= m1.cm.FN()) { fromM1 = false; mIndex -= m1.cm.FN(); } - //if we need to transfer quality - if (quality){ - Scalarm q = 0; //default quality value + // if we need to transfer quality + if (quality) { + Scalarm q = 0; // default quality value if (fromM1 && m1HasQuality) q = m1.cm.face[mIndex].Q(); if (!fromM1 && m2HasQuality) @@ -426,9 +413,9 @@ void FilterMeshBooleans::transferFaceAttributes( res.cm.face[i].Q() = q; } - //if we need to transfer color + // if we need to transfer color if (color) { - vcg::Color4b c(128, 128, 128, 255); //default color value + vcg::Color4b c(128, 128, 128, 255); // default color value if (fromM1 && m1HasColor) c = m1.cm.face[mIndex].C(); if (!fromM1 && m2HasColor) @@ -455,19 +442,19 @@ void FilterMeshBooleans::transferFaceAttributes( * @param color: if true, vertex color will be transferred */ void FilterMeshBooleans::transferVertexAttributes( - MeshModel& res, - const Eigen::VectorXi& faceIndices, - const MeshModel& m1, - const MeshModel& m2, - bool quality, - bool color) + MeshModel& res, + const Eigen::VectorXi& faceIndices, + const MeshModel& m1, + const MeshModel& m2, + bool quality, + bool color) { res.updateDataMask(MeshModel::MM_VERTFACETOPO); vcg::tri::UpdateTopology::VertexFace(res.cm); - //checking if m1 and m2 have quality and color + // checking if m1 and m2 have quality and color bool m1HasQuality = true, m1HasColor = true, m2HasQuality = true, m2HasColor = true; - if (quality){ + if (quality) { res.updateDataMask(MeshModel::MM_VERTQUALITY); if (!m1.hasDataMask(MeshModel::MM_VERTQUALITY)) m1HasQuality = false; @@ -482,34 +469,34 @@ void FilterMeshBooleans::transferVertexAttributes( m2HasColor = false; } - //vertIndices construction + // vertIndices construction Eigen::VectorXi vertIndices(res.cm.VN()); vertIndices.setConstant(-1); - for (unsigned int i = 0; i < faceIndices.size(); ++i){ - bool fromM1 = true; + for (unsigned int i = 0; i < faceIndices.size(); ++i) { + bool fromM1 = true; unsigned int mIndex = faceIndices[i]; - //if the index is >= FN of m1, it means that the index is of m2 - if (faceIndices[i] >= m1.cm.FN()){ + // if the index is >= FN of m1, it means that the index is of m2 + if (faceIndices[i] >= m1.cm.FN()) { fromM1 = false; mIndex -= m1.cm.FN(); } CMeshO::ConstFacePointer fBirth; - CMeshO::FacePointer fRes = &(res.cm.face[i]); + CMeshO::FacePointer fRes = &(res.cm.face[i]); if (fromM1) fBirth = &(m1.cm.face[mIndex]); else fBirth = &(m2.cm.face[mIndex]); - for (unsigned int j = 0; j < 3; ++j){ + for (unsigned int j = 0; j < 3; ++j) { CMeshO::VertexPointer vp = fRes->V(j); - unsigned int vi = vcg::tri::Index(res.cm, vp); - if (vertIndices[vi] == -1){ - //look if there is an equal vertex in fBirth - for (unsigned k = 0; k < 3; ++k){ - if (fRes->V(j)->P() == fBirth->V(k)->P()){ + unsigned int vi = vcg::tri::Index(res.cm, vp); + if (vertIndices[vi] == -1) { + // look if there is an equal vertex in fBirth + for (unsigned k = 0; k < 3; ++k) { + if (fRes->V(j)->P() == fBirth->V(k)->P()) { unsigned int birthVertIndex; if (fromM1) birthVertIndex = vcg::tri::Index(m1.cm, fBirth->V(k)); @@ -522,13 +509,13 @@ void FilterMeshBooleans::transferVertexAttributes( } } - //update birth vertices - for (unsigned int i = 0; i < vertIndices.size(); ++i){ + // update birth vertices + for (unsigned int i = 0; i < vertIndices.size(); ++i) { bool fromM1 = false; bool fromM2 = false; int mIndex = vertIndices[i]; - if (vertIndices[i] >= m1.cm.VN()){ + if (vertIndices[i] >= m1.cm.VN()) { fromM2 = true; mIndex -= m1.cm.VN(); } @@ -536,9 +523,9 @@ void FilterMeshBooleans::transferVertexAttributes( fromM1 = true; } - //if we need to transfer quality - if (quality){ - Scalarm q = 0; //default quality value + // if we need to transfer quality + if (quality) { + Scalarm q = 0; // default quality value if (fromM1 && m1HasQuality) q = m1.cm.vert[mIndex].Q(); if (!fromM1 && m2HasQuality) @@ -546,9 +533,9 @@ void FilterMeshBooleans::transferVertexAttributes( res.cm.vert[i].Q() = q; } - //if we need to transfer color + // if we need to transfer color if (color) { - vcg::Color4b c(128, 128, 128, 255); //default color value + vcg::Color4b c(128, 128, 128, 255); // default color value if (fromM1 && m1HasColor) c = m1.cm.vert[mIndex].C(); if (fromM2 && m2HasColor) @@ -557,43 +544,44 @@ void FilterMeshBooleans::transferVertexAttributes( } } - //update newly created vertices - for (unsigned int i = 0; i < vertIndices.size(); ++i){ - if (vertIndices[i] == -1){ - //base values - unsigned int avgr=0, avgg=0, avgb=0, avga=0; - Scalarm avgq=0; + // update newly created vertices + for (unsigned int i = 0; i < vertIndices.size(); ++i) { + if (vertIndices[i] == -1) { + // base values + unsigned int avgr = 0, avgg = 0, avgb = 0, avga = 0; + Scalarm avgq = 0; unsigned int nAdjs = 0; - CMeshO::VertexPointer vp = &res.cm.vert[i]; + CMeshO::VertexPointer vp = &res.cm.vert[i]; vcg::face::VFIterator fadjit(vp); - //for each incident face fadj to vp - for (; !fadjit.End(); ++fadjit){ - for (unsigned int j = 0; j < 3; j++){ - //get each vertex to f + // for each incident face fadj to vp + for (; !fadjit.End(); ++fadjit) { + for (unsigned int j = 0; j < 3; j++) { + // get each vertex to f CMeshO::VertexPointer vadj = fadjit.F()->V(j); - unsigned int vi = vcg::tri::Index(res.cm, vadj); - //if the vertex is not i and it is not newly created + unsigned int vi = vcg::tri::Index(res.cm, vadj); + // if the vertex is not i and it is not newly created if (vi != i && vertIndices[vi] != -1) { nAdjs++; - //if we need to transfer color + // if we need to transfer color if (color) { avgr += res.cm.vert[vi].C()[0]; avgg += res.cm.vert[vi].C()[1]; avgb += res.cm.vert[vi].C()[2]; avga += res.cm.vert[vi].C()[3]; } - if (quality){ + if (quality) { avgq += res.cm.vert[vi].Q(); } } } } - if (nAdjs != 0){ + if (nAdjs != 0) { if (color) { - res.cm.vert[i].C() = vcg::Color4b(avgr/nAdjs, avgg/nAdjs, avgb/nAdjs, avga/nAdjs); + res.cm.vert[i].C() = + vcg::Color4b(avgr / nAdjs, avgg / nAdjs, avgb / nAdjs, avga / nAdjs); } - if (quality){ + if (quality) { res.cm.vert[i].Q() = avgq / nAdjs; } } diff --git a/src/meshlabplugins/filter_mesh_booleans/filter_mesh_booleans.h b/src/meshlabplugins/filter_mesh_booleans/filter_mesh_booleans.h index c2c5794ee..0bff24614 100644 --- a/src/meshlabplugins/filter_mesh_booleans/filter_mesh_booleans.h +++ b/src/meshlabplugins/filter_mesh_booleans/filter_mesh_booleans.h @@ -1,25 +1,25 @@ -/**************************************************************************** -* MeshLab o o * -* A versatile mesh processing toolbox o o * -* _ O _ * -* Copyright(C) 2005-2021 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ +/***************************************************************************** + * MeshLab o o * + * A versatile mesh processing toolbox o o * + * _ O _ * + * Copyright(C) 2005-2021 \/)\/ * + * Visual Computing Lab /\/| * + * ISTI - Italian National Research Council | * + * \ * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * + * for more details. * + * * + ****************************************************************************/ #ifndef MESHLAB_FILTER_MESH_BOOLEANS_H #define MESHLAB_FILTER_MESH_BOOLEANS_H @@ -47,59 +47,55 @@ class FilterMeshBooleans : public QObject, public FilterPlugin Q_INTERFACES(FilterPlugin) public: - //enum used to give an ID to every filter implemented in the plugin - enum FileterIds { - MESH_INTERSECTION, - MESH_UNION, - MESH_DIFFERENCE, - MESH_XOR}; + // enum used to give an ID to every filter implemented in the plugin + enum FileterIds { MESH_INTERSECTION, MESH_UNION, MESH_DIFFERENCE, MESH_XOR }; FilterMeshBooleans(); QString pluginName() const; QString vendor() const; - QString filterName(ActionIDType filter) const; - QString filterInfo(ActionIDType filter) const; + QString filterName(ActionIDType filter) const; + QString filterInfo(ActionIDType filter) const; FilterClass getClass(const QAction* a) const; FilterArity filterArity(const QAction*) const; - //int getPreConditions(const QAction *) const; - //int postCondition(const QAction* ) const; - RichParameterList initParameterList(const QAction*, const MeshDocument &/*m*/); + // int getPreConditions(const QAction *) const; + // int postCondition(const QAction* ) const; + RichParameterList initParameterList(const QAction*, const MeshDocument& /*m*/); std::map applyFilter( - const QAction* action, - const RichParameterList & params, - MeshDocument &md, - unsigned int& postConditionMask, - vcg::CallBackPos * cb); + const QAction* action, + const RichParameterList& params, + MeshDocument& md, + unsigned int& postConditionMask, + vcg::CallBackPos* cb); private: - //generic boolean operation function + // generic boolean operation function static void booleanOperation( - MeshDocument& md, - const MeshModel& m1, - const MeshModel& m2, - int op, - bool transfFaceQuality, - bool transfFaceColor, - bool transfVertQuality, - bool transfVertColor); + MeshDocument& md, + const MeshModel& m1, + const MeshModel& m2, + int op, + bool transfFaceQuality, + bool transfFaceColor, + bool transfVertQuality, + bool transfVertColor); - //transfer functions + // transfer functions static void transferFaceAttributes( - MeshModel& res, - const Eigen::VectorXi& faceIndices, - const MeshModel& m1, - const MeshModel& m2, - bool quality, - bool color); + MeshModel& res, + const Eigen::VectorXi& faceIndices, + const MeshModel& m1, + const MeshModel& m2, + bool quality, + bool color); static void transferVertexAttributes( - MeshModel& res, - const Eigen::VectorXi& faceIndices, - const MeshModel& m1, - const MeshModel& m2, - bool quality, - bool color); + MeshModel& res, + const Eigen::VectorXi& faceIndices, + const MeshModel& m1, + const MeshModel& m2, + bool quality, + bool color); }; -#endif //MESHLAB_FILTER_MESH_BOOLEANS_H +#endif // MESHLAB_FILTER_MESH_BOOLEANS_H