# ----------------------------------
# - BBTKGEditor v 1.5 BBG BlackBox Diagram file
-# - /Users/davila/Creatis/C23/creatools_source/creaMaracasVisu/bbtk/bbs/boxes/Mesh_tool_ApplyDeformation.bbg
+# - /home/garzon/Creatis/C23/creatools_source/creaMaracasVisu/bbtk/bbs/boxes/Mesh_tool_ApplyDeformation.bbg
# ----------------------------------
APP_START
meshmanagermodel
-131.800179:136.578564:-900.000000
FIN_COMPLEX_PORT
-BOXES:97
+BOXES:104
BOX
wx:LayoutLine:Box08
ISEXEC:FALSE
BOX
creaVtk:MeshDeformation:Box39
ISEXEC:FALSE
--409.372374:-78.395244:-900.000000
--387.027374:-80.895244:-900.000000
+-378.393017:-93.884922:-900.000000
+-356.048017:-96.384922:-900.000000
PORT
TypeIn:"1"
FIN_BOX
BOX
itkvtk:GeodesicMeshDeformation:Box122
ISEXEC:FALSE
--422.007694:-58.443600:-900.000000
--398.592694:-60.943600:-900.000000
+-403.918349:-56.277211:-900.000000
+-380.503349:-58.777211:-900.000000
PORT
TypeIn:"1"
FIN_BOX
BOX
creaVtk:MeshManager_tool:Box134
ISEXEC:FALSE
--425.084450:-69.566462:-900.000000
--402.474450:-72.066462:-900.000000
+-403.203925:-69.349823:-900.000000
+-380.593925:-71.849823:-900.000000
PORT
BoxProcessMode:"Manual"
PORT
BOX
creaMaracasVisu:SetPosition:Box142
ISEXEC:FALSE
--467.892126:-121.805063:-900.000000
--446.122126:-124.305063:-900.000000
+-494.577133:-89.030543:-900.000000
+-472.807133:-91.530543:-900.000000
FIN_BOX
BOX
creaMaracasVisu:SetPosition:Box143
ISEXEC:FALSE
--424.237483:-120.561026:-900.000000
--402.467483:-123.061026:-900.000000
+-427.782482:-103.623806:-900.000000
+-406.012482:-106.123806:-900.000000
FIN_BOX
BOX
std:MathOperationVector:Box144
ISEXEC:FALSE
--443.371633:-73.718222:-900.000000
--418.851633:-76.218222:-900.000000
+-428.275200:-81.374566:-900.000000
+-403.755200:-83.874566:-900.000000
PORT
Type:"3"
FIN_BOX
BOX
std:MathOperationVector:Box145
ISEXEC:FALSE
--475.847435:-73.727505:-900.000000
--451.327435:-76.227505:-900.000000
+-487.703489:-77.262657:-900.000000
+-463.183489:-79.762657:-900.000000
PORT
Type:"3"
FIN_BOX
BOX
-creaVtk:PointPickerNearest:Box148
-ISEXEC:FALSE
--516.890064:-75.470080:-900.000000
--494.330064:-77.970080:-900.000000
-FIN_BOX
-BOX
creaVtk:PlaneWidget_Base:Box154
ISEXEC:FALSE
--460.584699:-132.025714:-900.000000
--438.064699:-134.525714:-900.000000
+-491.742062:-105.023699:-900.000000
+-469.222062:-107.523699:-900.000000
PORT
Type:"3"
FIN_BOX
BOX
creaVtk:PlaneWidget_Base:Box151
ISEXEC:FALSE
--431.925229:-141.181205:-900.000000
--409.405229:-143.681205:-900.000000
+-427.493980:-114.495237:-900.000000
+-404.973980:-116.995237:-900.000000
PORT
Type:"3"
FIN_BOX
-CONNECTIONS:187
+BOX
+std:GetVectorDoubleSubVector:Box150
+ISEXEC:FALSE
+-504.285188:-69.695126:-900.000000
+-480.825188:-72.195126:-900.000000
+PORT
+ErrorValue:"0"
+PORT
+I:"0"
+PORT
+Size:"3"
+FIN_BOX
+BOX
+std:GetVectorDoubleSubVector:Box152
+ISEXEC:FALSE
+-527.842488:-65.457779:-900.000000
+-504.382488:-67.957779:-900.000000
+PORT
+ErrorValue:"0"
+PORT
+I:"3"
+PORT
+Size:"3"
+FIN_BOX
+BOX
+creaVtk:PlaneWidget_Base:Box153
+ISEXEC:FALSE
+-518.932987:-104.134406:-900.000000
+-496.412987:-106.634406:-900.000000
+PORT
+Type:"2"
+FIN_BOX
+BOX
+std:GetVectorDoubleSubVector:Box155
+ISEXEC:FALSE
+-445.750811:-61.855849:-900.000000
+-422.290811:-64.355849:-900.000000
+PORT
+ErrorValue:"0"
+PORT
+I:"0"
+PORT
+Size:"3"
+FIN_BOX
+BOX
+std:GetVectorDoubleSubVector:Box156
+ISEXEC:FALSE
+-460.293139:-94.614799:-900.000000
+-436.833139:-97.114799:-900.000000
+PORT
+ErrorValue:"0"
+PORT
+I:"3"
+PORT
+Size:"3"
+FIN_BOX
+BOX
+creaVtk:PlaneWidget_Base:Box158
+ISEXEC:FALSE
+-455.810818:-113.848455:-900.000000
+-433.290818:-116.348455:-900.000000
+PORT
+Type:"2"
+FIN_BOX
+BOX
+std:ConcatStrings_tool:Box159
+ISEXEC:FALSE
+-518.749463:-47.336915:-900.000000
+-496.199463:-49.836915:-900.000000
+PORT
+BoxProcessMode:"Manual"
+PORT
+In1:"-1"
+PORT
+Type:"1"
+FIN_BOX
+BOX
+std:MultipleInputs:Box160
+ISEXEC:FALSE
+-518.170784:-36.309478:-900.000000
+-496.090784:-38.809478:-900.000000
+FIN_BOX
+CONNECTIONS:202
CONNECTION
Box08:Widget:widget:widget
NumberOfControlPoints:0
Box96:wxVtkBaseView:Box142:wxVtkBaseView
NumberOfControlPoints:0
CONNECTION
-Box138:Out:Box144:In0
-NumberOfControlPoints:0
-CONNECTION
Box83:Spacing:Box144:In1
NumberOfControlPoints:0
CONNECTION
-Box137:Out:Box145:In0
-NumberOfControlPoints:0
-CONNECTION
Box83:Spacing:Box145:In1
NumberOfControlPoints:0
CONNECTION
Box144:Out:Box143:Point
NumberOfControlPoints:0
CONNECTION
-Box137:Out:Box154:ParamVector
+Box137:Out:Box150:In
+NumberOfControlPoints:0
+CONNECTION
+Box150:Out:Box145:In0
+NumberOfControlPoints:0
+CONNECTION
+Box150:Out:Box154:ParamVector
+NumberOfControlPoints:0
+CONNECTION
+Box137:Out:Box152:In
+NumberOfControlPoints:0
+CONNECTION
+Box142:BoxChange:Box153:BoxExecute
+NumberOfControlPoints:0
+CONNECTION
+Box58:Base:Box153:In
+NumberOfControlPoints:0
+CONNECTION
+Box138:Out:Box155:In
+NumberOfControlPoints:0
+CONNECTION
+Box155:Out:Box144:In0
+NumberOfControlPoints:0
+CONNECTION
+Box138:Out:Box156:In
+NumberOfControlPoints:0
+CONNECTION
+Box155:Out:Box151:ParamVector
+NumberOfControlPoints:0
+CONNECTION
+Box156:Out:Box158:ParamVector
+NumberOfControlPoints:0
+CONNECTION
+Box143:BoxChange:Box158:BoxExecute
+NumberOfControlPoints:0
+CONNECTION
+Box58:Base:Box158:In
+NumberOfControlPoints:0
+CONNECTION
+Box152:Out:Box153:ParamVector
+NumberOfControlPoints:0
+CONNECTION
+Box58:Normal:Box122:Direction
+NumberOfControlPoints:0
+CONNECTION
+Box102:Box_ConcatStrings:Box159:Box_ConcatString
+NumberOfControlPoints:0
+CONNECTION
+Box160:BoxChange:Box159:BoxExecute
+NumberOfControlPoints:0
+CONNECTION
+Box131:BoxChange:Box160:In1
NumberOfControlPoints:0
CONNECTION
-Box138:Out:Box151:ParamVector
+Box132:BoxChange:Box160:In2
NumberOfControlPoints:0
APP_END
# ----------------------------------
# - BBTKGEditor v 1.5 BBS BlackBox Script (Complex Box)
-# - /Users/davila/Creatis/C23/creatools_source/creaMaracasVisu/bbtk/bbs/boxes/Mesh_tool_ApplyDeformation.bbs
+# - /home/garzon/Creatis/C23/creatools_source/creaMaracasVisu/bbtk/bbs/boxes/Mesh_tool_ApplyDeformation.bbs
# ----------------------------------
include std
new std:MathOperationVector Box145
set Box145.Type "3"
-new creaVtk:PointPickerNearest Box148
-
new creaVtk:PlaneWidget_Base Box154
set Box154.Type "3"
new creaVtk:PlaneWidget_Base Box151
set Box151.Type "3"
+new std:GetVectorDoubleSubVector Box150
+ set Box150.ErrorValue "0"
+ set Box150.I "0"
+ set Box150.Size "3"
+
+new std:GetVectorDoubleSubVector Box152
+ set Box152.ErrorValue "0"
+ set Box152.I "3"
+ set Box152.Size "3"
+
+new creaVtk:PlaneWidget_Base Box153
+ set Box153.Type "2"
+
+new std:GetVectorDoubleSubVector Box155
+ set Box155.ErrorValue "0"
+ set Box155.I "0"
+ set Box155.Size "3"
+
+new std:GetVectorDoubleSubVector Box156
+ set Box156.ErrorValue "0"
+ set Box156.I "3"
+ set Box156.Size "3"
+
+new creaVtk:PlaneWidget_Base Box158
+ set Box158.Type "2"
+
+new std:ConcatStrings_tool Box159
+ set Box159.BoxProcessMode "Manual"
+ set Box159.In1 "-1"
+ set Box159.Type "1"
+
+new std:MultipleInputs Box160
+
connect Box66.Out Box11.Renderer
connect Box66.Out Box37.render
connect Box58.BoxChange Box89.BoxExecute
connect Box122.Out Box134.DoubleParams
connect Box96.wxVtkBaseView Box142.wxVtkBaseView
-connect Box138.Out Box144.In0
connect Box83.Spacing Box144.In1
-connect Box137.Out Box145.In0
connect Box83.Spacing Box145.In1
connect Box145.Out Box142.Point
connect Box96.wxVtkBaseView Box143.wxVtkBaseView
connect Box142.BoxChange Box154.BoxExecute
connect Box143.BoxChange Box151.BoxExecute
connect Box144.Out Box143.Point
-connect Box137.Out Box154.ParamVector
-connect Box138.Out Box151.ParamVector
+connect Box137.Out Box150.In
+connect Box150.Out Box145.In0
+connect Box150.Out Box154.ParamVector
+connect Box137.Out Box152.In
+connect Box142.BoxChange Box153.BoxExecute
+connect Box58.Base Box153.In
+connect Box138.Out Box155.In
+connect Box155.Out Box144.In0
+connect Box138.Out Box156.In
+connect Box155.Out Box151.ParamVector
+connect Box156.Out Box158.ParamVector
+connect Box143.BoxChange Box158.BoxExecute
+connect Box58.Base Box158.In
+connect Box152.Out Box153.ParamVector
+connect Box58.Normal Box122.Direction
+connect Box102.Box_ConcatStrings Box159.Box_ConcatString
+connect Box160.BoxChange Box159.BoxExecute
+connect Box131.BoxChange Box160.In1
+connect Box132.BoxChange Box160.In2
# Complex input ports
input mesh Box67.In " "
void ShowNPoints_Tools::SeparateSplines()
{
WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
- if((wsp->GetLstModelShowNPointsSize() > 0) && (bbGetInputParams().size() == 3))
+ if((wsp->GetLstModelShowNPointsSize() > 0) && (bbGetInputParams().size() == 6))
{
- std::vector<double> refPoint = bbGetInputParams();
- std::vector<double> pointsX, pointsY, pointsZ;
+ std::vector<double> refPoint = {bbGetInputParams()[0], bbGetInputParams()[1], bbGetInputParams()[2]};
+ std::vector<double> pointsX, pointsY, pointsZ, refPlaneNorm, planeNormal;
std::vector<std::vector<std::vector<double>>> newGroups;
std::vector<std::vector<double>> planesNorm;
- double rotAxis[3] = {0,0,1};
+ std::vector<double> rotAxis = {bbGetInputParams()[3], bbGetInputParams()[4], bbGetInputParams()[5]}; ;
- double vector1[3], vector2[3], planeNormal[3], rotatedNormal[3], axisPoint[3], refPlaneNorm[3];
- int idPoint2, idPoint3;
+ std::vector<double> intersectionTop, intersectionBottom;
int numGroups = wsp->GetLstModelShowNPointsSize();
for(int i = 0; i < numGroups; i++){
pointsY = wsp->GetModelShowNPoints(i)->GetLstPointsY();
pointsZ = wsp->GetModelShowNPoints(i)->GetLstPointsZ();
- idPoint2 = ((int)pointsX.size()/3)-1;
- idPoint3 = idPoint2*2;
-
- vector1[0] = pointsX[idPoint2]-refPoint[0];
- vector1[1] = pointsY[idPoint2]-refPoint[1];
- vector1[2] = pointsZ[idPoint2]-refPoint[2];
-
- vector2[0] = pointsX[idPoint3]-refPoint[0];
- vector2[1] = pointsY[idPoint3]-refPoint[1];
- vector2[2] = pointsZ[idPoint3]-refPoint[2];
-
- vtkMath::Cross(vector1, vector2, planeNormal);
- vtkMath::Normalize(planeNormal);
- vtkMath::Cross(planeNormal, rotAxis, rotatedNormal);
- vtkMath::Normalize(rotatedNormal);
-
+ planeNormal = GetPlaneNormalFromPointsRefPoint(pointsX, pointsY, pointsZ, refPoint);
+
if(i == 0){
- std::copy(std::begin(planeNormal), std::end(planeNormal), std::begin(refPlaneNorm));
+ refPlaneNorm = planeNormal;
}
- std::vector<std::vector<double>> pointsOver, pointsUnder, pointsOn;
- std::vector<double> point(3);
- for(int j = 0; j < pointsX.size(); j++){
- point[0] = pointsX[j];
- point[1] = pointsY[j];
- point[2] = pointsZ[j];
- vtkMath::Subtract(point.data(), refPoint.data(), vector1);
- if(vtkMath::Dot(vector1, rotatedNormal) > 0){
- pointsOver.push_back(point);
+ //Get points over, under and on plane, all groups ordered in the direction of the axis.
+ std::vector<std::vector<std::vector<double>>> pointsAroundPlane;
+ pointsAroundPlane = GetOrderedPointsAroundPlane(refPoint, planeNormal, rotAxis, pointsX, pointsY, pointsZ);
+ std::vector<std::vector<double>> pointsOver = pointsAroundPlane[0];
+ std::vector<std::vector<double>> pointsUnder = pointsAroundPlane[1];
+ std::vector<std::vector<double>> pointsOn = pointsAroundPlane[2];
+
+ //Calculate points where splines should intersect
+ double middlePoint[3];
+ if(intersectionTop.empty() && intersectionBottom.empty()){
+ if(!pointsOver.empty() && !pointsUnder.empty()){
+ vtkMath::Add(pointsOver.back().data(), pointsUnder.back().data(), middlePoint);
+ vtkMath::MultiplyScalar(middlePoint, 0.5);
+ intersectionTop = GetProjectionPointOnAxis(middlePoint, refPoint.data(), rotAxis.data());
+
+ vtkMath::Add(pointsOver.front().data(), pointsUnder.front().data(), middlePoint);
+ vtkMath::MultiplyScalar(middlePoint, 0.5);
+ intersectionBottom = GetProjectionPointOnAxis(middlePoint, refPoint.data(), rotAxis.data());
+ }
+ else if(!pointsOn.empty()){
+ intersectionTop = pointsOn.back();
+ intersectionBottom = pointsOn.front();
}
- else if (vtkMath::Dot(vector1, rotatedNormal) < 0){
- pointsUnder.push_back(point);
+ else{
+ intersectionTop = pointsOver.empty()?pointsUnder.back():pointsOver.back();
+ intersectionBottom = pointsOver.empty()?pointsUnder.front():pointsOver.front();
}
- //else{
- // pointsOn.push_back(j);
- //}
}
-
- std::vector<double> normalToSave(std::begin(planeNormal), std::end(planeNormal));
- if(!pointsOver.empty()){
+
+ //Save groups and their normals
+ if(!pointsOver.empty()){
+ pointsOver.push_back(intersectionTop);
+ pointsOver.insert(pointsOver.begin(), intersectionBottom);
newGroups.push_back(pointsOver);
- planesNorm.push_back(normalToSave);
+ planesNorm.push_back(planeNormal);
}
- if(!pointsUnder.empty()){
- std::reverse(pointsUnder.begin(), pointsUnder.end());
+ if(!pointsUnder.empty()){
+ pointsUnder.push_back(intersectionTop);
+ pointsUnder.insert(pointsUnder.begin(), intersectionBottom);
newGroups.push_back(pointsUnder);
- vtkMath::MultiplyScalar(planeNormal, -1);
- normalToSave[0] = planeNormal[0]; normalToSave[1] = planeNormal[1]; normalToSave[2] = planeNormal[2];
- planesNorm.push_back(normalToSave);
+ double tempPlaneNorm[3] = {planeNormal[0], planeNormal[1], planeNormal[2]};
+ vtkMath::MultiplyScalar(tempPlaneNorm, -1);
+ planeNormal[0] = tempPlaneNorm[0]; planeNormal[1] = tempPlaneNorm[1]; planeNormal[2] = tempPlaneNorm[2];
+ planesNorm.push_back(planeNormal);
}
-
-
}
+ //Sort Groups by their plane angles, from the first plane around the rotation axis
auto comp = [&](int id1,int id2)-> bool {
- //double dot = vtkMath::Dot(planesNorm[id1].data(), refPlaneNorm);
- //double det = vtkMath::Determinant3x3(planesNorm[id1].data(), refPlaneNorm, rotAxis);
- //double angle1 = atan2(det, dot);
- double angle1 = vtkMath::SignedAngleBetweenVectors(planesNorm[id1].data(), refPlaneNorm, rotAxis);
+ double angle1 = vtkMath::SignedAngleBetweenVectors(planesNorm[id1].data(), refPlaneNorm.data(), rotAxis.data());
if(angle1 < 0) angle1 += 2*vtkMath::Pi();
- double angle2 = vtkMath::SignedAngleBetweenVectors(planesNorm[id2].data(), refPlaneNorm, rotAxis);
+ double angle2 = vtkMath::SignedAngleBetweenVectors(planesNorm[id2].data(), refPlaneNorm.data(), rotAxis.data());
if(angle2 < 0) angle2 += 2*vtkMath::Pi();
return angle1 < angle2;
};
std::iota(std::begin(indexVect), std::end(indexVect), 0);
std::sort(indexVect.begin(), indexVect.end(), comp);
+ //Build Groups
wsp->ResetCollections_();
for(int i = 0; i < newGroups.size(); i++){
std::vector<std::vector<double>> group = newGroups[indexVect[i]];
wsp->InsertCollectionAfter_();
}
}
+ wsp->InvertLstPoints_();
wsp->SetOutputBox();
wsp->UndoRedo_SaveCollection();
}
}
+std::vector<std::vector<std::vector<double>>> ShowNPoints_Tools::GetOrderedPointsAroundPlane(std::vector<double> planeOrigin, std::vector<double> planeNormal, std::vector<double> rotAxis, std::vector<double> pX, std::vector<double> pY, std::vector<double> pZ){
+
+ std::vector<std::vector<double>> pointsOver, pointsUnder, pointsOn;
+ std::vector<double> point(3);
+ double rotatedNormal[3], vector1[3];
+ vtkMath::Cross(planeNormal.data(), rotAxis.data(), rotatedNormal);
+ vtkMath::Normalize(rotatedNormal);
+
+ bool changedSide = false;
+ int startingSide = -1; //-1 not started, 0 over, 1 under
+ int placedElements = 0;
+ for(int j = 0; j < pX.size(); j++){
+ point[0] = pX[j];
+ point[1] = pY[j];
+ point[2] = pZ[j];
+ vtkMath::Subtract(point.data(), planeOrigin.data(), vector1);
+ if(vtkMath::Dot(vector1, rotatedNormal) > 0){
+ if(!pointsUnder.empty()){
+ changedSide = true;
+ }
+ else {
+ startingSide = 0;
+ }
+
+ if(changedSide && startingSide == 0){
+ pointsOver.insert(pointsOver.begin()+placedElements, point);
+ placedElements++;
+ }
+ else{
+ pointsOver.push_back(point);
+ }
+ }
+ else if (vtkMath::Dot(vector1, rotatedNormal) < 0){
+ if(!pointsOver.empty())
+ {
+ changedSide = true;
+ }
+ else startingSide = 1;
+
+ if(changedSide && startingSide == 1){
+ pointsUnder.insert(pointsUnder.begin()+placedElements, point);
+ placedElements++;
+ }
+ else{
+ pointsUnder.push_back(point);
+ }
+ }
+ else{
+ pointsOn.push_back(point);
+ }
+ }
+ ////////
+ /// Check direction of points and reverse if needed.
+ /// Always follows axis vector direction
+ ////////
+ if(pointsUnder.size() > 2){
+ vtkMath::Subtract(pointsUnder.front(), pointsUnder.back(), vector1);
+ double dot = vtkMath::Dot(vector1, rotAxis.data());
+ if(dot < 0){
+ std::reverse(pointsUnder.begin(), pointsUnder.end());
+ if(startingSide == 1 && !pointsOn.empty()){
+ std::reverse(pointsOn.begin(), pointsOn.end());
+ }
+ }
+ }
+ if(pointsOver.size() > 2){
+ vtkMath::Subtract(pointsOver.front(), pointsOver.back(), vector1);
+ double dot = vtkMath::Dot(vector1, rotAxis.data());
+ if(dot < 0){
+ std::reverse(pointsOver.begin(), pointsOver.end());
+ if(startingSide == 0 && !pointsOn.empty()){
+ std::reverse(pointsOn.begin(), pointsOn.end());
+ }
+ }
+ }
+
+ std::vector<std::vector<std::vector<double>>> results = {pointsOver, pointsUnder, pointsOn};
+ return results;
+}
+
+std::vector<double> ShowNPoints_Tools::GetPlaneNormalFromPointsRefPoint(std::vector<double> pointsX, std::vector<double> pointsY, std::vector<double> pointsZ, std::vector<double> refPoint)
+{
+ double vector1[3], vector2[3], planeNormal[3];
+ int idPoint2, idPoint3;
+ idPoint2 = ((int)pointsX.size()/3)-1;
+ idPoint3 = ((int)pointsX.size()/2)+1;
+
+ vector1[0] = pointsX[idPoint2]-refPoint[0];
+ vector1[1] = pointsY[idPoint2]-refPoint[1];
+ vector1[2] = pointsZ[idPoint2]-refPoint[2];
+
+ vector2[0] = pointsX[idPoint3]-refPoint[0];
+ vector2[1] = pointsY[idPoint3]-refPoint[1];
+ vector2[2] = pointsZ[idPoint3]-refPoint[2];
+
+ vtkMath::Cross(vector1, vector2, planeNormal);
+ vtkMath::Normalize(planeNormal);
+
+ std::vector<double> result(std::begin(planeNormal), std::end(planeNormal));
+ return result;
+}
+
+std::vector<double> ShowNPoints_Tools::GetProjectionPointOnAxis(double pointToProject[3], double originAxis[3], double axisDir[3])
+{
+ double projectionVect[3], vectorToPoint[3], pointProjected[3];
+ vtkMath::Subtract(pointToProject, originAxis, vectorToPoint);
+
+ vtkMath::ProjectVector(vectorToPoint, axisDir, projectionVect);
+ vtkMath::Add(originAxis, projectionVect, pointProjected);
+
+ std::vector<double> result(std::begin(pointProjected), std::end(pointProjected));
+ return result;
+}
+
+
//=====
// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
//=====