2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008,2009 Oliver Gloth +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "insertpoints.h"
25 #include "guimainwindow.h"
27 #include <vtkCharArray.h>
31 InsertPoints::InsertPoints()
37 void InsertPoints::operate()
39 int N1
= grid
->GetNumberOfPoints();
40 if(insert_FP
) insert_FP_all();
41 if(insert_EP
) insert_EP_all();
42 int N2
= grid
->GetNumberOfPoints();
43 m_NumInserted
= N2
- N1
;
46 bool InsertPoints::insert_fieldpoint(vtkIdType id_cell
)
48 double Fred1
=1.0/sqrt(3);
49 double Qmin
=1.1;//1.189;
53 vtkIdType cell
= getPartC2C()[id_cell
][i
];
54 if( cell
!= -1 ) total
+= Q_L(cell
);
56 return ( Q_L(id_cell
)>1.0/Fred1
&& total
>3*Qmin
);
59 bool InsertPoints::insert_edgepoint(vtkIdType id_node1
, vtkIdType id_node2
)
61 bool result
= distance(grid
, id_node1
, id_node2
) > 0.5 * ( desiredEdgeLength(id_node1
) + desiredEdgeLength(id_node2
) );
65 bool InsertPoints::SplitSide(vtkIdType id_cell
,int side
)
68 grid
->GetCellPoints(id_cell
,N_pts
,pts
);
69 return( insert_edgepoint(pts
[side
],pts
[(side
+1)%N_pts
]) );
72 int InsertPoints::insert_FP_all()
74 //cout<<"===insert_FP_all START==="<<endl;
75 QTime start
= QTime::currentTime();
78 UpdatePotentialSnapPoints(true);
80 QVector
<vtkIdType
> l_SelectedCells
;
81 getSurfaceCells(m_bcs
, l_SelectedCells
, grid
);
83 QVector
<bool> l_marked_cells(l_SelectedCells
.size());
89 for(int i_cell
=0;i_cell
<l_SelectedCells
.size();i_cell
++)
91 vtkIdType id_cell
= l_SelectedCells
[i_cell
];
92 if( insert_fieldpoint(id_cell
) )
94 l_marked_cells
[i_cell
] = true;
100 //initialize grid_tmp
101 int l_N_points
= grid
->GetNumberOfPoints();
102 int l_N_cells
= grid
->GetNumberOfCells();
103 EG_VTKSP(vtkUnstructuredGrid
,grid_tmp
);
104 allocateGrid(grid_tmp
,l_N_cells
+l_N_newcells
,l_N_points
+l_N_newpoints
);
105 makeCopyNoAlloc(grid
, grid_tmp
);
107 //initialize new node counter
108 vtkIdType l_newNodeId
= l_N_points
;
111 for(int i_cell
=0;i_cell
<l_SelectedCells
.size();i_cell
++)
113 vtkIdType id_cell
= l_SelectedCells
[i_cell
];
114 if( l_marked_cells
[i_cell
] )
116 vtkIdType N_pts
, *pts
;
117 grid
->GetCellPoints(id_cell
, N_pts
, pts
);
119 for(int i
=0;i
<N_pts
;i
++)
122 grid
->GetPoints()->GetPoint(pts
[i
], corner
.data());
125 C
=(1/(double)N_pts
)*C
;
128 grid_tmp
->GetPoints()->SetPoint(l_newNodeId
,C
.data());
129 copyNodeData(grid_tmp
,pts
[0],grid_tmp
,l_newNodeId
);
130 EG_VTKDCN(vtkCharArray
, node_type
, grid_tmp
, "node_type");
131 node_type
->SetValue(l_newNodeId
, VTK_SIMPLE_VERTEX
);
133 for(int i
=0;i
<N_pts
;i
++)
135 vtkIdType pts_triangle
[3];
136 pts_triangle
[0]=pts
[i
];
137 pts_triangle
[1]=pts
[(i
+1)%N_pts
];
138 pts_triangle
[2]=l_newNodeId
;
141 grid_tmp
->ReplaceCell(id_cell
, 3, pts_triangle
);
145 vtkIdType newCellId
= grid_tmp
->InsertNextCell(VTK_TRIANGLE
,3,pts_triangle
);
146 copyCellData(grid_tmp
,id_cell
,grid_tmp
,newCellId
);
154 makeCopy(grid_tmp
,grid
);
156 //cout << start.msecsTo(QTime::currentTime()) << " milliseconds elapsed" << endl;
157 //cout<<"===insert_FP_all END==="<<endl;
161 int InsertPoints::insert_EP_all()
163 l2g_t cells
= getPartCells();
164 g2l_t _cells
= getPartLocalCells();
166 //cout<<"===insert_EP_all START==="<<endl;
167 QTime start
= QTime::currentTime();
169 setAllSurfaceCells();
170 UpdatePotentialSnapPoints(true);
172 EG_VTKDCC(vtkIntArray
, cell_code
, grid
, "cell_code");
177 QVector
<int> marked_cells(cells
.size());
178 QVector
<stencil_t
> stencil_vector(cells
.size());
181 for (int i
= 0; i
< cells
.size(); ++i
) {
182 vtkIdType id_cell
= cells
[i
];
183 if (m_bcs
.contains(cell_code
->GetValue(id_cell
)) && (grid
->GetCellType(id_cell
) == VTK_TRIANGLE
)) {//if selected and triangle cell
186 vtkIdType N_pts
, *pts
;
187 grid
->GetCellPoints(id_cell
, N_pts
, pts
);
188 for (int j
= 0; j
< 3; ++j
) {
189 vtkIdType id_node1
= pts
[j
];
190 vtkIdType id_node2
= pts
[(j
+1)%N_pts
];
191 double L
= distance(grid
, id_node1
, id_node2
);
192 if (L
> max(desiredEdgeLength(id_node1
), desiredEdgeLength(id_node2
))) {
200 stencil_t S
= getStencil(id_cell
, j_split
);
201 if (S
.twocells
&& (S
.neighbour_type
== VTK_TRIANGLE
)) {
202 if (!marked_cells
[i
] && !marked_cells
[_cells
[S
.id_cell2
]]) {
203 stencil_vector
[i
] = S
;
205 marked_cells
[_cells
[S
.id_cell2
]] = 2;
209 } else if (!S
.twocells
) {
210 if (!marked_cells
[i
]) {
211 stencil_vector
[i
] = S
;
217 } //end of loop through sides
218 } //end of if selected and triangle cell
219 } //end of counter loop
221 //initialize grid_tmp
222 int l_N_points
=grid
->GetNumberOfPoints();
223 int l_N_cells
=grid
->GetNumberOfCells();
224 EG_VTKSP(vtkUnstructuredGrid
,grid_tmp
);
225 allocateGrid(grid_tmp
, l_N_cells
+ num_newcells
, l_N_points
+ num_newpoints
);
226 makeCopyNoAlloc(grid
, grid_tmp
);
228 //initialize new node counter
229 vtkIdType l_newNodeId
= l_N_points
;
232 for (int i
= 0; i
< cells
.size(); i
++) {
233 if (marked_cells
[i
] == 1) {
234 stencil_t S
= stencil_vector
[i
];
238 grid_tmp
->GetPoint(S
.p
[1],A
.data());
239 grid_tmp
->GetPoint(S
.p
[3],B
.data());
245 grid_tmp
->GetPoints()->SetPoint(l_newNodeId
, M
.data());
246 copyNodeData(grid_tmp
,S
.p
[1],grid_tmp
,l_newNodeId
);
248 // inserted edge point = type of the edge on which it is inserted
249 EG_VTKDCN(vtkCharArray
, node_type
, grid_tmp
, "node_type");
250 node_type
->SetValue(l_newNodeId
, getNewNodeType(S
) );
252 if(S
.twocells
&& S
.neighbour_type
==VTK_TRIANGLE
){//2 triangles
254 vtkIdType pts_triangle
[4][3];
257 pts_triangle
[i
][0]=S
.p
[i
];
258 pts_triangle
[i
][1]=S
.p
[(i
+1)%4];
259 pts_triangle
[i
][2]=l_newNodeId
;
262 grid_tmp
->ReplaceCell(S
.id_cell1
, 3, pts_triangle
[0]);
263 grid_tmp
->ReplaceCell(S
.id_cell2
, 3, pts_triangle
[1]);
267 newCellId
= grid_tmp
->InsertNextCell(VTK_TRIANGLE
,3,pts_triangle
[2]);
268 copyCellData(grid_tmp
,S
.id_cell2
,grid_tmp
,newCellId
);
270 newCellId
= grid_tmp
->InsertNextCell(VTK_TRIANGLE
,3,pts_triangle
[3]);
271 copyCellData(grid_tmp
,S
.id_cell1
,grid_tmp
,newCellId
);
273 else if(!S
.twocells
) {//1 triangle
275 vtkIdType pts_triangle
[2][3];
276 pts_triangle
[0][0]=S
.p
[0];
277 pts_triangle
[0][1]=S
.p
[1];
278 pts_triangle
[0][2]=l_newNodeId
;
279 pts_triangle
[1][0]=S
.p
[3];
280 pts_triangle
[1][1]=S
.p
[0];
281 pts_triangle
[1][2]=l_newNodeId
;
283 grid_tmp
->ReplaceCell(S
.id_cell1
, 3, pts_triangle
[0]);
286 newCellId
= grid_tmp
->InsertNextCell(VTK_TRIANGLE
,3,pts_triangle
[1]);
287 copyCellData(grid_tmp
,S
.id_cell1
,grid_tmp
,newCellId
);
290 cout
<<"I DON'T KNOW HOW TO SPLIT THIS CELL!!!"<<endl
;
300 makeCopy(grid_tmp
,grid
);
302 //cout << start.msecsTo(QTime::currentTime()) << " milliseconds elapsed" << endl;
303 //cout<<"===insert_EP_all END==="<<endl;
307 char InsertPoints::getNewNodeType(stencil_t S
)
309 vtkIdType id_node1
= S
.p
[1];
310 vtkIdType id_node2
= S
.p
[3];
312 EG_VTKDCN(vtkCharArray
, node_type
, grid
, "node_type");
313 if( node_type
->GetValue(id_node1
)==VTK_SIMPLE_VERTEX
|| node_type
->GetValue(id_node2
)==VTK_SIMPLE_VERTEX
) {
314 return VTK_SIMPLE_VERTEX
;
317 QVector
<vtkIdType
> PSP
= getPotentialSnapPoints(id_node1
);
318 if( PSP
.contains(id_node2
) ) {
319 EG_VTKDCC(vtkIntArray
, cell_code
, grid
, "cell_code");
320 if( cell_code
->GetValue(S
.id_cell1
) != cell_code
->GetValue(S
.id_cell2
) ) {
321 return VTK_BOUNDARY_EDGE_VERTEX
;
324 return VTK_FEATURE_EDGE_VERTEX
;
328 return VTK_SIMPLE_VERTEX
;
333 //============================================
334 ///@@@ TODO: Update node info (densities+type) Still necessary?
335 // EG_VTKDCN(vtkIntArray, node_specified_density, grid_tmp, "node_specified_density");//density index from table
336 // EG_VTKDCN(vtkDoubleArray, node_meshdensity_desired, grid_tmp, "node_meshdensity_desired");//what we want
337 // EG_VTKDCN(vtkDoubleArray, node_meshdensity_current, grid_tmp, "node_meshdensity_current");//what we have
338 // EG_VTKDCN(vtkCharArray, node_type, grid_tmp, "node_type");//node type
339 //============================================
342 // node_type->SetValue(l_newNodeId,VTK_SIMPLE_VERTEX);
345 // double total_dist=0;
346 // double avg_dist=0;
347 // for(int i=0;i<N_pts;i++)
349 // double dist=(corner[i]-C).abs();
351 // node_meshdensity_current->SetValue(pts[i],NewCurrentMeshDensity(pts[i],dist));
353 // avg_dist=total_dist/(double)N_pts;
354 // node_meshdensity_current->SetValue(l_newNodeId,1./avg_dist);
357 // VertexMeshDensity nodeVMD;
358 // nodeVMD.type=node_type->GetValue(l_newNodeId);
359 // nodeVMD.density=0;
360 // nodeVMD.CurrentNode=l_newNodeId;
361 // EG_VTKDCC(vtkIntArray, cell_code, grid, "cell_code");
362 // nodeVMD.BCmap[cell_code->GetValue(id_cell)]=2;
364 // int idx=VMDvector.indexOf(nodeVMD);
365 // node_specified_density->SetValue(l_newNodeId, idx);
368 // if(idx!=-1)//specified
370 // node_meshdensity_desired->SetValue(l_newNodeId, VMDvector[idx].density);
374 // double D=DesiredMeshDensity(l_newNodeId);
375 // node_meshdensity_desired->SetValue(l_newNodeId, D);
378 //============================================