Skip to content

Commit c37ae92

Browse files
committed
Implemented extrude tool that can use a map, read from a file, to adjust the local extrusion direction and distance.
1 parent fbe6bad commit c37ae92

6 files changed

+282
-10
lines changed

FEBioStudio/DlgImportData.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,13 @@ class Ui::CDlgImportData
9797
{
9898
commaButton->setChecked(true);
9999
}
100-
else
100+
else if (data.count('\t') > 0)
101+
{
102+
tabButton->setChecked(true);
103+
}
104+
else
101105
{
102-
tabButton->setChecked(true);
106+
spaceButton->setChecked(true);
103107
}
104108

105109
separatorLayout->addWidget(otherSeparator = new QLineEdit(";"));
@@ -316,6 +320,11 @@ void CDlgImportData::UpdateTable()
316320
}
317321
}
318322

323+
if (ui->numCols == -1)
324+
{
325+
ui->numCols = cols;
326+
}
327+
319328
if(cols < ui->numCols)
320329
{
321330
cols = ui->numCols;

FEBioStudio/ExtrudeMapTool.cpp

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*This file is part of the FEBio Studio source code and is licensed under the MIT license
2+
listed below.
3+
4+
See Copyright-FEBio-Studio.txt for details.
5+
6+
Copyright (c) 2021 University of Utah, The Trustees of Columbia University in
7+
the City of New York, and others.
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in all
17+
copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25+
SOFTWARE.*/
26+
#include "stdafx.h"
27+
#include "ExtrudeMapTool.h"
28+
#include <MeshTools/FEExtrudeFaces.h>
29+
#include "ModelDocument.h"
30+
#include "MainWindow.h"
31+
#include <GeomLib/GMeshObject.h>
32+
#include <QFile>
33+
#include <MeshLib/FENodeData.h>
34+
#include "DlgImportData.h"
35+
36+
CExtrudeMapTool::CExtrudeMapTool(CMainWindow* wnd) : CBasicTool(wnd, "Extrude map", HAS_APPLY_BUTTON)
37+
{
38+
m_D = 1;
39+
m_nsegs = 1;
40+
m_useLocalNormal = true;
41+
m_meshBias = 1;
42+
m_symmetricBias = false;
43+
addResourceProperty(&m_filename, "map file:");
44+
addDoubleProperty(&m_D, "distance");
45+
addIntProperty(&m_nsegs, "segments");
46+
addBoolProperty(&m_useLocalNormal, "use local normal");
47+
addDoubleProperty(&m_meshBias, "mesh bias");
48+
addBoolProperty(&m_symmetricBias, "symmetric mesh bias");
49+
}
50+
51+
bool CExtrudeMapTool::OnApply()
52+
{
53+
GMeshObject* po = dynamic_cast<GMeshObject*>(GetActiveObject());
54+
if (po == nullptr)
55+
{
56+
SetErrorString("You need to select an Editable Mesh object.");
57+
return false;
58+
}
59+
60+
FSMesh* pm = po->GetFEMesh();
61+
if (pm == nullptr)
62+
{
63+
SetErrorString("The selected object has no mesh.");
64+
return false;
65+
}
66+
67+
int n = pm->CountSelectedFaces();
68+
if (n == 0)
69+
{
70+
SetErrorString("No faces are selected. Cannot apply tool.");
71+
return false;
72+
}
73+
74+
vector<int> node;
75+
vector<double> data[3];
76+
77+
QFile mapFile(m_filename);
78+
if (!mapFile.open(QIODeviceBase::Text | QIODeviceBase::ReadOnly))
79+
{
80+
SetErrorString("mapFile.errorString()");
81+
return false;
82+
}
83+
84+
QTextStream in(&mapFile);
85+
QString txt = in.readAll();
86+
mapFile.close();
87+
88+
CDlgImportData dlg(txt, DataType::DOUBLE);
89+
if (!dlg.exec()) return true;
90+
91+
QList<QStringList> values = dlg.GetValues();
92+
for (QStringList& fields : values)
93+
{
94+
int n = fields.count();
95+
if ((n != 2) && (n != 4))
96+
{
97+
SetErrorString("Invalid data in map file.");
98+
return false;
99+
}
100+
node.push_back(fields[0].toInt());
101+
for (int i = 0; i < n - 1; ++i)
102+
{
103+
double di = fields.at(i + 1).toDouble();
104+
data[i].push_back(di);
105+
}
106+
}
107+
108+
int fields = 1;
109+
if ((data[0].size() == data[1].size()) &&
110+
(data[0].size() == data[2].size())) fields = 3;
111+
112+
// create a nodeset
113+
FSNodeSet nodeSet(po);
114+
for (int i = 0; i < node.size(); ++i)
115+
{
116+
int nid = node[i];
117+
int m = pm->NodeIndexFromID(nid);
118+
nodeSet.add(m);
119+
}
120+
121+
// create a data map
122+
FENodeData map(po);
123+
if (fields == 1)
124+
{
125+
map.Create(&nodeSet, 0, DATA_SCALAR);
126+
for (int i = 0; i < node.size(); ++i)
127+
{
128+
map.set(i, data[0][i]);
129+
}
130+
}
131+
else
132+
{
133+
map.Create(&nodeSet, 0, DATA_VEC3);
134+
for (int i = 0; i < node.size(); ++i)
135+
{
136+
map.set(i, vec3d(data[0][i], data[1][i], data[2][i]));
137+
}
138+
}
139+
140+
FEExtrudeFaces mod;
141+
mod.SetExtrusionDistance(m_D);
142+
mod.SetSegments(m_nsegs);
143+
mod.SetUseNormalLocal(m_useLocalNormal);
144+
mod.SetMeshBiasFactor(m_meshBias);
145+
mod.SetSymmetricBias(m_symmetricBias);
146+
mod.SetNodalMap(&map);
147+
148+
CModelDocument* doc = dynamic_cast<CModelDocument*>(GetDocument());
149+
bool b = doc->ApplyFEModifier(mod, GetActiveObject());
150+
if (!b) SetErrorString(QString::fromStdString(mod.GetErrorString()));
151+
updateUi();
152+
153+
return b;
154+
}

FEBioStudio/ExtrudeMapTool.h

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*This file is part of the FEBio Studio source code and is licensed under the MIT license
2+
listed below.
3+
4+
See Copyright-FEBio-Studio.txt for details.
5+
6+
Copyright (c) 2021 University of Utah, The Trustees of Columbia University in
7+
the City of New York, and others.
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in all
17+
copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25+
SOFTWARE.*/
26+
#pragma once
27+
#include "Tool.h"
28+
#include <vector>
29+
30+
class CExtrudeMapTool : public CBasicTool
31+
{
32+
public:
33+
CExtrudeMapTool(CMainWindow* wnd);
34+
35+
bool OnApply() override;
36+
37+
private:
38+
QString m_filename;
39+
double m_D;
40+
int m_nsegs;
41+
bool m_useLocalNormal;
42+
double m_meshBias;
43+
bool m_symmetricBias;
44+
};

FEBioStudio/ToolsPanel.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ SOFTWARE.*/
4545
#include "SelectNearPlaneTool.h"
4646
#include "KinematBuildTool.h"
4747
#include "MeshMorphTool.h"
48+
#include "ExtrudeMapTool.h"
4849

4950
CToolsPanel::CToolsPanel(CMainWindow* wnd, QWidget* parent) : CCommandPanel(wnd, parent), ui(new Ui::CToolsPanel)
5051
{
@@ -81,6 +82,7 @@ void CToolsPanel::initTools()
8182
tools.push_back(new CSelectNearPlaneTool(wnd));
8283
tools.push_back(new CKinematBuildTool (wnd));
8384
tools.push_back(new CMeshMorphTool (wnd));
85+
tools.push_back(new CExtrudeMapTool (wnd));
8486
}
8587

8688
void CToolsPanel::on_buttons_idClicked(int id)

MeshTools/FEExtrudeFaces.cpp

+64-7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ FEExtrudeFaces::FEExtrudeFaces() : FEModifier("Extrude faces")
3636
AddBoolParam(false, "L", "Use local normal");
3737
AddDoubleParam(1, "mesh bias");
3838
AddBoolParam(false, "symmetric mesh bias");
39+
40+
m_map = nullptr;
3941
}
4042

4143
void FEExtrudeFaces::SetExtrusionDistance(double D)
@@ -63,6 +65,11 @@ void FEExtrudeFaces::SetSymmetricBias(bool b)
6365
SetBoolValue(4, b);
6466
}
6567

68+
void FEExtrudeFaces::SetNodalMap(FENodeData* map)
69+
{
70+
m_map = map;
71+
}
72+
6673
FSMesh* FEExtrudeFaces::Apply(FSGroup* pg)
6774
{
6875
if (pg->Type() != FE_SURFACE)
@@ -99,12 +106,16 @@ FSMesh* FEExtrudeFaces::Apply(FSMesh* pm)
99106
}
100107

101108
FSMesh* pnm = new FSMesh(*pm);
102-
Extrude(pnm, faceList);
109+
if (!Extrude(pnm, faceList))
110+
{
111+
delete pnm;
112+
pnm = nullptr;
113+
}
103114

104115
return pnm;
105116
}
106117

107-
void FEExtrudeFaces::Extrude(FSMesh* pm, vector<int>& faceList)
118+
bool FEExtrudeFaces::Extrude(FSMesh* pm, vector<int>& faceList)
108119
{
109120
// let's mark the nodes that need to be copied
110121
pm->TagAllNodes(-1);
@@ -118,7 +129,7 @@ void FEExtrudeFaces::Extrude(FSMesh* pm, vector<int>& faceList)
118129
int n = face.Nodes();
119130

120131
// extrusion is only allowed on tris and quads!
121-
if ((n != 4) && (n != 3) && (n != 9) && (n != 8) && (n != 6)) return;
132+
if ((n != 4) && (n != 3) && (n != 9) && (n != 8) && (n != 6)) return false;
122133

123134
if ((n == 9) || (n == 8) || (n == 6)) linear = false;
124135

@@ -127,17 +138,21 @@ void FEExtrudeFaces::Extrude(FSMesh* pm, vector<int>& faceList)
127138
}
128139

129140
// make sure there was something selected
130-
if (ne1 == 0) return;
141+
if (ne1 == 0) return false;
131142

132143
// count the nodes
133144
int n0 = pm->Nodes();
134145
int nn = 0;
135-
for (int i = 0; i<n0; ++i)
136-
if (pm->Node(i).m_ntag > 0)
146+
for (int i = 0; i < n0; ++i)
147+
{
148+
FSNode& node = pm->Node(i);
149+
if (node.m_ntag > 0)
137150
{
138-
pm->Node(i).m_ntag = nn;
151+
node.m_ntag = nn;
139152
++nn;
140153
}
154+
else node.m_ntag = -1;
155+
}
141156

142157
double dist = GetFloatValue(0);
143158
int nseg = GetIntValue(1);
@@ -176,6 +191,46 @@ void FEExtrudeFaces::Extrude(FSMesh* pm, vector<int>& faceList)
176191
// make sure all directional vectors are normalized
177192
for (int i = 0; i<nn; ++i) ed[i].Normalize();
178193

194+
// apply nodal map
195+
if (m_map)
196+
{
197+
FSNodeSet* nset = dynamic_cast<FSNodeSet*>(m_map->GetItemList());
198+
if (nset == nullptr) return error("Invalid nodal map specified.");
199+
200+
vector<int> tag(n0, -1);
201+
for (int i = 0; i < n0; ++i)
202+
if (pm->Node(i).m_ntag >= 0)
203+
{
204+
tag[i] = pm->Node(i).m_ntag;
205+
}
206+
207+
if (m_map->GetDataType() == DATA_SCALAR)
208+
{
209+
auto it = nset->begin();
210+
for (int i = 0; i < nset->size(); ++i, ++it)
211+
{
212+
int m = tag[*it];
213+
if (m == -1) return error("Invalid nodal map specified.");
214+
215+
double v = m_map->get(i);
216+
ed[m] *= v;
217+
}
218+
}
219+
else if (m_map->GetDataType() == DATA_VEC3)
220+
{
221+
auto it = nset->begin();
222+
for (int i = 0; i < nset->size(); ++i, ++it)
223+
{
224+
int m = tag[*it];
225+
if (m == -1) return error("Invalid nodal map specified.");
226+
227+
vec3d v = m_map->getVec3d(i);
228+
ed[m] = v * dist;
229+
}
230+
}
231+
else return error("Invalid nodal data map specified.");
232+
}
233+
179234
double fd = gd;
180235
gd = 1;
181236
if (bd)
@@ -479,4 +534,6 @@ void FEExtrudeFaces::Extrude(FSMesh* pm, vector<int>& faceList)
479534
// delete extraneous nodes (if any)
480535
FEMeshBuilder meshBuilder(*pm);
481536
meshBuilder.RemoveIsolatedNodes();
537+
538+
return true;
482539
}

MeshTools/FEExtrudeFaces.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SOFTWARE.*/
2626

2727
#pragma once
2828
#include "FEModifier.h"
29+
#include <MeshLib/FENodeData.h>
2930

3031
class FEExtrudeFaces : public FEModifier
3132
{
@@ -41,6 +42,11 @@ class FEExtrudeFaces : public FEModifier
4142
void SetMeshBiasFactor(double g);
4243
void SetSymmetricBias(bool b);
4344

45+
void SetNodalMap(FENodeData* map);
46+
4447
protected:
45-
void Extrude(FSMesh* pm, std::vector<int>& faceList);
48+
bool Extrude(FSMesh* pm, std::vector<int>& faceList);
49+
50+
private:
51+
FENodeData* m_map;
4652
};

0 commit comments

Comments
 (0)