mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-24 21:10:33 +05:00
Merge branch 'master' into 'shirnschall'
# Conflicts: # libsrc/occ/python_occ_shapes.cpp
This commit is contained in:
commit
964a3cc06b
@ -369,6 +369,9 @@ namespace netgen
|
|||||||
|
|
||||||
double u = gi.u;
|
double u = gi.u;
|
||||||
double v = gi.v;
|
double v = gi.v;
|
||||||
|
#ifdef OLD
|
||||||
|
// was a problem for pheres: got u-v paramters outside range of definition
|
||||||
|
|
||||||
gp_Pnt x = occface->Value (u,v);
|
gp_Pnt x = occface->Value (u,v);
|
||||||
|
|
||||||
if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return;
|
if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return;
|
||||||
@ -418,7 +421,7 @@ namespace netgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (count < 20);
|
while (count < 20);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Newton did not converge, use OCC projection
|
// Newton did not converge, use OCC projection
|
||||||
|
|
||||||
|
@ -323,9 +323,9 @@ DLL_HEADER void ExportNgOCC(py::module &m)
|
|||||||
|
|
||||||
cout << "handle(shape) = " << *(void**)(void*)(&(shape.TShape())) << endl;
|
cout << "handle(shape) = " << *(void**)(void*)(&(shape.TShape())) << endl;
|
||||||
|
|
||||||
TDF_LabelSequence doc_shapes;
|
// TDF_LabelSequence doc_shapes;
|
||||||
shape_tool->GetShapes(doc_shapes);
|
// shape_tool->GetShapes(doc_shapes);
|
||||||
cout << "shape tool nbentities: " << doc_shapes.Size() << endl;
|
// cout << "shape tool nbentities: " << doc_shapes.Size() << endl;
|
||||||
TDF_Label label = shape_tool -> FindShape(shape);
|
TDF_Label label = shape_tool -> FindShape(shape);
|
||||||
cout << "shape label = " << endl << label << endl;
|
cout << "shape label = " << endl << label << endl;
|
||||||
if (label.IsNull()) return;
|
if (label.IsNull()) return;
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include <Standard_GUID.hxx>
|
#include <Standard_GUID.hxx>
|
||||||
#include <Geom_TrimmedCurve.hxx>
|
#include <Geom_TrimmedCurve.hxx>
|
||||||
#include <Geom_Plane.hxx>
|
#include <Geom_Plane.hxx>
|
||||||
|
#include <Geom_BSplineCurve.hxx>
|
||||||
|
#include <Geom_BezierCurve.hxx>
|
||||||
#include <GC_MakeSegment.hxx>
|
#include <GC_MakeSegment.hxx>
|
||||||
#include <GC_MakeCircle.hxx>
|
#include <GC_MakeCircle.hxx>
|
||||||
#include <GC_MakeArcOfCircle.hxx>
|
#include <GC_MakeArcOfCircle.hxx>
|
||||||
@ -47,6 +49,8 @@
|
|||||||
#include <GCE2d_MakeSegment.hxx>
|
#include <GCE2d_MakeSegment.hxx>
|
||||||
#include <GCE2d_MakeCircle.hxx>
|
#include <GCE2d_MakeCircle.hxx>
|
||||||
#include <GCE2d_MakeArcOfCircle.hxx>
|
#include <GCE2d_MakeArcOfCircle.hxx>
|
||||||
|
#include <ShapeUpgrade_UnifySameDomain.hxx>
|
||||||
|
#include <GeomLProp_SLProps.hxx>
|
||||||
|
|
||||||
#if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=4
|
#if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=4
|
||||||
#define OCC_HAVE_DUMP_JSON
|
#define OCC_HAVE_DUMP_JSON
|
||||||
@ -54,6 +58,59 @@
|
|||||||
|
|
||||||
using namespace netgen;
|
using namespace netgen;
|
||||||
|
|
||||||
|
void ExtractEdgeData( const TopoDS_Edge & edge, int index, std::vector<double> * p, Box<3> & box )
|
||||||
|
{
|
||||||
|
if (BRep_Tool::Degenerated(edge)) return;
|
||||||
|
|
||||||
|
Handle(Poly_PolygonOnTriangulation) poly;
|
||||||
|
Handle(Poly_Triangulation) T;
|
||||||
|
TopLoc_Location loc;
|
||||||
|
BRep_Tool::PolygonOnTriangulation(edge, poly, T, loc);
|
||||||
|
|
||||||
|
int nbnodes = poly -> NbNodes();
|
||||||
|
for (int j = 1; j < nbnodes; j++)
|
||||||
|
{
|
||||||
|
auto p0 = occ2ng((T -> Nodes())(poly->Nodes()(j)).Transformed(loc));
|
||||||
|
auto p1 = occ2ng((T -> Nodes())(poly->Nodes()(j+1)).Transformed(loc));
|
||||||
|
for(auto k : Range(3))
|
||||||
|
{
|
||||||
|
p[0].push_back(p0[k]);
|
||||||
|
p[1].push_back(p1[k]);
|
||||||
|
}
|
||||||
|
p[0].push_back(index);
|
||||||
|
p[1].push_back(index);
|
||||||
|
box.Add(p0);
|
||||||
|
box.Add(p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtractFaceData( const TopoDS_Face & face, int index, std::vector<double> * p, Box<3> & box )
|
||||||
|
{
|
||||||
|
TopLoc_Location loc;
|
||||||
|
Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc);
|
||||||
|
|
||||||
|
bool flip = TopAbs_REVERSED == face.Orientation();
|
||||||
|
|
||||||
|
int ntriangles = triangulation -> NbTriangles();
|
||||||
|
for (int j = 1; j <= ntriangles; j++)
|
||||||
|
{
|
||||||
|
Poly_Triangle triangle = (triangulation -> Triangles())(j);
|
||||||
|
std::array<Point<3>,3> pts;
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
pts[k] = occ2ng( (triangulation -> Nodes())(triangle(k+1)).Transformed(loc) );
|
||||||
|
|
||||||
|
if(flip)
|
||||||
|
Swap(pts[1], pts[2]);
|
||||||
|
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
box.Add(pts[k]);
|
||||||
|
for (int d = 0; d < 3; d++)
|
||||||
|
p[k].push_back( pts[k][d] );
|
||||||
|
p[k].push_back( index );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
py::object CastShape(const TopoDS_Shape & s)
|
py::object CastShape(const TopoDS_Shape & s)
|
||||||
{
|
{
|
||||||
@ -478,7 +535,13 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
{ return shape.Located(loc); })
|
{ return shape.Located(loc); })
|
||||||
|
|
||||||
.def("__add__", [] (const TopoDS_Shape & shape1, const TopoDS_Shape & shape2) {
|
.def("__add__", [] (const TopoDS_Shape & shape1, const TopoDS_Shape & shape2) {
|
||||||
return BRepAlgoAPI_Fuse(shape1, shape2).Shape();
|
auto fused = BRepAlgoAPI_Fuse(shape1, shape2).Shape();
|
||||||
|
return fused;
|
||||||
|
// make one face when fusing in 2D
|
||||||
|
// from https://gitlab.onelab.info/gmsh/gmsh/-/issues/627
|
||||||
|
// ShapeUpgrade_UnifySameDomain unify(fused, true, true, true);
|
||||||
|
// unify.Build();
|
||||||
|
// return unify.Shape();
|
||||||
})
|
})
|
||||||
|
|
||||||
.def("__mul__", [] (const TopoDS_Shape & shape1, const TopoDS_Shape & shape2) {
|
.def("__mul__", [] (const TopoDS_Shape & shape1, const TopoDS_Shape & shape2) {
|
||||||
@ -652,6 +715,105 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
// return MoveToNumpyArray(triangles);
|
// return MoveToNumpyArray(triangles);
|
||||||
return triangles;
|
return triangles;
|
||||||
})
|
})
|
||||||
|
.def("_webgui_data", [](const TopoDS_Shape & shape)
|
||||||
|
{
|
||||||
|
BRepTools::Clean (shape);
|
||||||
|
double deflection = 0.01;
|
||||||
|
BRepMesh_IncrementalMesh (shape, deflection, true);
|
||||||
|
// triangulation = BRep_Tool::Triangulation (face, loc);
|
||||||
|
|
||||||
|
std::vector<double> p[3];
|
||||||
|
py::list names, colors;
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
Box<3> box(Box<3>::EMPTY_BOX);
|
||||||
|
for (TopExp_Explorer e(shape, TopAbs_FACE); e.More(); e.Next())
|
||||||
|
{
|
||||||
|
TopoDS_Face face = TopoDS::Face(e.Current());
|
||||||
|
// Handle(TopoDS_Face) face = e.Current();
|
||||||
|
ExtractFaceData(face, index, p, box);
|
||||||
|
auto & props = OCCGeometry::global_shape_properties[face.TShape()];
|
||||||
|
if(props.col)
|
||||||
|
{
|
||||||
|
auto & c = *props.col;
|
||||||
|
colors.append(py::make_tuple(c[0], c[1], c[2]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
colors.append(py::make_tuple(0.0, 1.0, 0.0));
|
||||||
|
if(props.name)
|
||||||
|
{
|
||||||
|
names.append(*props.name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
names.append("");
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> edge_p[2];
|
||||||
|
py::list edge_names, edge_colors;
|
||||||
|
index = 0;
|
||||||
|
for (TopExp_Explorer e(shape, TopAbs_EDGE); e.More(); e.Next())
|
||||||
|
{
|
||||||
|
TopoDS_Edge edge = TopoDS::Edge(e.Current());
|
||||||
|
ExtractEdgeData(edge, index, edge_p, box);
|
||||||
|
auto & props = OCCGeometry::global_shape_properties[edge.TShape()];
|
||||||
|
if(props.col)
|
||||||
|
{
|
||||||
|
auto & c = *props.col;
|
||||||
|
edge_colors.append(py::make_tuple(c[0], c[1], c[2]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
edge_colors.append(py::make_tuple(0.0, 0.0, 0.0));
|
||||||
|
if(props.name)
|
||||||
|
{
|
||||||
|
edge_names.append(*props.name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
edge_names.append("");
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto center = box.Center();
|
||||||
|
|
||||||
|
py::list mesh_center;
|
||||||
|
mesh_center.append(center[0]);
|
||||||
|
mesh_center.append(center[1]);
|
||||||
|
mesh_center.append(center[2]);
|
||||||
|
py::dict data;
|
||||||
|
data["ngsolve_version"] = "Netgen x.x"; // TODO
|
||||||
|
data["mesh_dim"] = 3; // TODO
|
||||||
|
data["mesh_center"] = mesh_center;
|
||||||
|
data["mesh_radius"] = box.Diam()/2;
|
||||||
|
data["order2d"] = 1;
|
||||||
|
data["order3d"] = 0;
|
||||||
|
data["draw_vol"] = false;
|
||||||
|
data["draw_surf"] = true;
|
||||||
|
data["funcdim"] = 0;
|
||||||
|
data["show_wireframe"] = true;
|
||||||
|
data["show_mesh"] = true;
|
||||||
|
data["Bezier_points"] = py::list{};
|
||||||
|
py::list points;
|
||||||
|
points.append(p[0]);
|
||||||
|
points.append(p[1]);
|
||||||
|
points.append(p[2]);
|
||||||
|
data["Bezier_trig_points"] = points;
|
||||||
|
data["funcmin"] = 0;
|
||||||
|
data["funcmax"] = 1;
|
||||||
|
data["mesh_regions_2d"] = index;
|
||||||
|
data["autoscale"] = false;
|
||||||
|
data["colors"] = colors;
|
||||||
|
data["names"] = names;
|
||||||
|
|
||||||
|
py::list edges;
|
||||||
|
edges.append(edge_p[0]);
|
||||||
|
edges.append(edge_p[1]);
|
||||||
|
data["edges"] = edges;
|
||||||
|
data["edge_names"] = edge_names;
|
||||||
|
data["edge_colors"] = edge_colors;
|
||||||
|
return data;
|
||||||
|
})
|
||||||
;
|
;
|
||||||
|
|
||||||
py::class_<TopoDS_Vertex, TopoDS_Shape> (m, "TopoDS_Vertex")
|
py::class_<TopoDS_Vertex, TopoDS_Shape> (m, "TopoDS_Vertex")
|
||||||
@ -678,6 +840,22 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
auto curve = BRep_Tool::Curve(e, s0, s1);
|
auto curve = BRep_Tool::Curve(e, s0, s1);
|
||||||
return curve->Value(s1);
|
return curve->Value(s1);
|
||||||
})
|
})
|
||||||
|
.def_property_readonly("start_tangent",
|
||||||
|
[](const TopoDS_Edge & e) {
|
||||||
|
double s0, s1;
|
||||||
|
auto curve = BRep_Tool::Curve(e, s0, s1);
|
||||||
|
gp_Pnt p; gp_Vec v;
|
||||||
|
curve->D1(s0, p, v);
|
||||||
|
return v;
|
||||||
|
})
|
||||||
|
.def_property_readonly("end_tangent",
|
||||||
|
[](const TopoDS_Edge & e) {
|
||||||
|
double s0, s1;
|
||||||
|
auto curve = BRep_Tool::Curve(e, s0, s1);
|
||||||
|
gp_Pnt p; gp_Vec v;
|
||||||
|
curve->D1(s1, p, v);
|
||||||
|
return v;
|
||||||
|
})
|
||||||
;
|
;
|
||||||
py::class_<TopoDS_Wire, TopoDS_Shape> (m, "TopoDS_Wire");
|
py::class_<TopoDS_Wire, TopoDS_Shape> (m, "TopoDS_Wire");
|
||||||
py::class_<TopoDS_Face, TopoDS_Shape> (m, "TopoDS_Face")
|
py::class_<TopoDS_Face, TopoDS_Shape> (m, "TopoDS_Face")
|
||||||
@ -711,6 +889,13 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
surf->D1 (u,v,p,du,dv);
|
surf->D1 (u,v,p,du,dv);
|
||||||
return tuple(p,du,dv);
|
return tuple(p,du,dv);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
.def("Normal", [] (const Handle(Geom_Surface) & surf, double u, double v) {
|
||||||
|
GeomLProp_SLProps lprop(surf,u,v,1,1e-8);
|
||||||
|
if (lprop.IsNormalDefined())
|
||||||
|
return lprop.Normal();
|
||||||
|
throw Exception("normal not defined");
|
||||||
|
})
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
@ -958,6 +1143,55 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
}, py::arg("p1"), py::arg("v"), py::arg("p2"));
|
}, py::arg("p1"), py::arg("v"), py::arg("p2"));
|
||||||
|
|
||||||
|
|
||||||
|
m.def("BSplineCurve", [](std::vector<gp_Pnt> vpoles, int degree) {
|
||||||
|
// not yet working ????
|
||||||
|
TColgp_Array1OfPnt poles(0, vpoles.size()-1);
|
||||||
|
TColStd_Array1OfReal knots(0, vpoles.size()+degree);
|
||||||
|
TColStd_Array1OfInteger mult(0, vpoles.size()+degree);
|
||||||
|
int cnt = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (int i = 0; i < vpoles.size(); i++)
|
||||||
|
{
|
||||||
|
poles.SetValue(i, vpoles[i]);
|
||||||
|
knots.SetValue(i, i);
|
||||||
|
mult.SetValue(i,1);
|
||||||
|
}
|
||||||
|
for (int i = vpoles.size(); i < vpoles.size()+degree+1; i++)
|
||||||
|
{
|
||||||
|
knots.SetValue(i, i);
|
||||||
|
mult.SetValue(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle(Geom_Curve) curve = new Geom_BSplineCurve(poles, knots, mult, degree);
|
||||||
|
return BRepBuilderAPI_MakeEdge(curve).Edge();
|
||||||
|
}
|
||||||
|
catch (Standard_Failure & e)
|
||||||
|
{
|
||||||
|
stringstream errstr;
|
||||||
|
e.Print(errstr);
|
||||||
|
throw NgException("cannot create spline: "+errstr.str());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m.def("BezierCurve", [](std::vector<gp_Pnt> vpoles) {
|
||||||
|
TColgp_Array1OfPnt poles(0, vpoles.size()-1);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (int i = 0; i < vpoles.size(); i++)
|
||||||
|
poles.SetValue(i, vpoles[i]);
|
||||||
|
|
||||||
|
Handle(Geom_Curve) curve = new Geom_BezierCurve(poles);
|
||||||
|
return BRepBuilderAPI_MakeEdge(curve).Edge();
|
||||||
|
}
|
||||||
|
catch (Standard_Failure & e)
|
||||||
|
{
|
||||||
|
stringstream errstr;
|
||||||
|
e.Print(errstr);
|
||||||
|
throw NgException("cannot create Bezier-spline: "+errstr.str());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
m.def("Edge", [](Handle(Geom2d_Curve) curve2d, TopoDS_Face face) {
|
m.def("Edge", [](Handle(Geom2d_Curve) curve2d, TopoDS_Face face) {
|
||||||
auto edge = BRepBuilderAPI_MakeEdge(curve2d, BRep_Tool::Surface (face)).Edge();
|
auto edge = BRepBuilderAPI_MakeEdge(curve2d, BRep_Tool::Surface (face)).Edge();
|
||||||
BRepLib::BuildCurves3d(edge);
|
BRepLib::BuildCurves3d(edge);
|
||||||
@ -966,32 +1200,25 @@ DLL_HEADER void ExportNgOCCShapes(py::module &m)
|
|||||||
|
|
||||||
m.def("Wire", [](std::vector<TopoDS_Shape> edges) {
|
m.def("Wire", [](std::vector<TopoDS_Shape> edges) {
|
||||||
BRepBuilderAPI_MakeWire builder;
|
BRepBuilderAPI_MakeWire builder;
|
||||||
for (auto s : edges)
|
|
||||||
switch (s.ShapeType())
|
|
||||||
{
|
|
||||||
case TopAbs_EDGE:
|
|
||||||
try
|
|
||||||
{
|
|
||||||
builder.Add(TopoDS::Edge(s)); break;
|
|
||||||
}
|
|
||||||
catch (Standard_Failure & e)
|
|
||||||
{
|
|
||||||
e.Print(cout);
|
|
||||||
throw NgException("cannot add to wire");
|
|
||||||
}
|
|
||||||
case TopAbs_WIRE:
|
|
||||||
builder.Add(TopoDS::Wire(s)); break;
|
|
||||||
default:
|
|
||||||
throw Exception("can make wire only from edges and wires");
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
for (auto s : edges)
|
||||||
|
switch (s.ShapeType())
|
||||||
|
{
|
||||||
|
case TopAbs_EDGE:
|
||||||
|
builder.Add(TopoDS::Edge(s)); break;
|
||||||
|
case TopAbs_WIRE:
|
||||||
|
builder.Add(TopoDS::Wire(s)); break;
|
||||||
|
default:
|
||||||
|
throw Exception("can make wire only from edges and wires");
|
||||||
|
}
|
||||||
return builder.Wire();
|
return builder.Wire();
|
||||||
}
|
}
|
||||||
catch (Standard_Failure & e)
|
catch (Standard_Failure & e)
|
||||||
{
|
{
|
||||||
e.Print(cout);
|
stringstream errstr;
|
||||||
throw NgException("error in wire builder");
|
e.Print(errstr);
|
||||||
|
throw NgException("error in wire builder: "+errstr.str());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ configure_file(__init__.py ${CMAKE_CURRENT_BINARY_DIR}/__init__.py @ONLY)
|
|||||||
install(FILES
|
install(FILES
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/__init__.py
|
${CMAKE_CURRENT_BINARY_DIR}/__init__.py
|
||||||
meshing.py csg.py geom2d.py stl.py gui.py NgOCC.py occ.py read_gmsh.py
|
meshing.py csg.py geom2d.py stl.py gui.py NgOCC.py occ.py read_gmsh.py
|
||||||
|
webgui.py
|
||||||
DESTINATION ${NG_INSTALL_DIR_PYTHON}/${NG_INSTALL_SUFFIX}
|
DESTINATION ${NG_INSTALL_DIR_PYTHON}/${NG_INSTALL_SUFFIX}
|
||||||
COMPONENT netgen
|
COMPONENT netgen
|
||||||
)
|
)
|
||||||
|
250
python/webgui.py
Normal file
250
python/webgui.py
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
import math
|
||||||
|
import numpy as np
|
||||||
|
from time import time
|
||||||
|
import os
|
||||||
|
|
||||||
|
from webgui_jupyter_widgets import BaseWebGuiScene, encodeData, WebGuiDocuWidget
|
||||||
|
import webgui_jupyter_widgets.widget as wg
|
||||||
|
|
||||||
|
class WebGLScene(BaseWebGuiScene):
|
||||||
|
def __init__(self, mesh, clipping, on_init):
|
||||||
|
from IPython.display import display, Javascript
|
||||||
|
import threading
|
||||||
|
self.mesh = mesh
|
||||||
|
self.clipping = clipping
|
||||||
|
self.on_init = on_init
|
||||||
|
|
||||||
|
def GetData(self, set_minmax=True):
|
||||||
|
import json
|
||||||
|
# d = BuildRenderData(self.mesh, self.cf, self.order, draw_surf=self.draw_surf, draw_vol=self.draw_vol, deformation=self.deformation, region=self.region)
|
||||||
|
d = self.mesh._webgui_data()
|
||||||
|
bp = d['Bezier_trig_points']
|
||||||
|
for i in range(len(bp)):
|
||||||
|
bp[i] = encodeData(np.array(bp[i]))
|
||||||
|
|
||||||
|
ep = d['edges']
|
||||||
|
for i in range(len(ep)):
|
||||||
|
ep[i] = encodeData(np.array(ep[i]))
|
||||||
|
|
||||||
|
if self.clipping is not None:
|
||||||
|
d['clipping'] = True
|
||||||
|
if isinstance(self.clipping, dict):
|
||||||
|
allowed_args = ("x", "y", "z", "dist", "function", "pnt", "vec")
|
||||||
|
if "vec" in self.clipping:
|
||||||
|
vec = self.clipping["vec"]
|
||||||
|
self.clipping["x"] = vec[0]
|
||||||
|
self.clipping["y"] = vec[1]
|
||||||
|
self.clipping["z"] = vec[2]
|
||||||
|
if "pnt" in self.clipping:
|
||||||
|
d['mesh_center'] = list(self.clipping["pnt"])
|
||||||
|
for name, val in self.clipping.items():
|
||||||
|
if not (name in allowed_args):
|
||||||
|
raise Exception('Only {} allowed as arguments for clipping!'.format(", ".join(allowed_args)))
|
||||||
|
d['clipping_' + name] = val
|
||||||
|
|
||||||
|
if self.on_init:
|
||||||
|
d['on_init'] = self.on_init
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
bezier_trig_trafos = { } # cache trafos for different orders
|
||||||
|
|
||||||
|
def BuildRenderData(mesh, func, order=2, draw_surf=True, draw_vol=True, deformation=None, region=True):
|
||||||
|
d = {}
|
||||||
|
d['ngsolve_version'] = "Netgen"
|
||||||
|
d['mesh_dim'] = 3 # mesh.dim TODO
|
||||||
|
|
||||||
|
d['order2d'] = 1
|
||||||
|
d['order3d'] = 0
|
||||||
|
|
||||||
|
d['draw_vol'] = False
|
||||||
|
d['draw_surf'] = True
|
||||||
|
d['funcdim'] = 1
|
||||||
|
|
||||||
|
func2 = None
|
||||||
|
if func and func.is_complex:
|
||||||
|
d['is_complex'] = True
|
||||||
|
func1 = func[0].real
|
||||||
|
func2 = ngs.CoefficientFunction( (func[0].imag, 0.0) )
|
||||||
|
elif func and func.dim>1:
|
||||||
|
func1 = func[0]
|
||||||
|
func2 = ngs.CoefficientFunction( tuple(func[i] if i<func.dim else 0.0 for i in range(1,3)) ) # max 3-dimensional functions
|
||||||
|
d['funcdim'] = func.dim
|
||||||
|
elif func:
|
||||||
|
func1 = func
|
||||||
|
d['funcdim'] = 1
|
||||||
|
else:
|
||||||
|
# no function at all -> we are just drawing a mesh, eval mesh element index instead
|
||||||
|
mats = mesh.GetMaterials()
|
||||||
|
bnds = mesh.GetBoundaries()
|
||||||
|
nmats = len(mesh.GetMaterials())
|
||||||
|
nbnds = len(mesh.GetBoundaries())
|
||||||
|
n = max(nmats, nbnds)
|
||||||
|
func1 = ngs.CoefficientFunction(list(range(n)))
|
||||||
|
n_regions = [0, 0, nmats, nbnds]
|
||||||
|
d['mesh_regions_2d'] = n_regions[mesh.dim]
|
||||||
|
d['mesh_regions_3d'] = nmats if mesh.dim==3 else 0
|
||||||
|
d['funcdim'] = 0
|
||||||
|
func1 = ngs.CoefficientFunction( (ngs.x, ngs.y, ngs.z, func1 ) )
|
||||||
|
func0 = ngs.CoefficientFunction( (ngs.x, ngs.y, ngs.z, 0.0 ) )
|
||||||
|
if deformation is not None:
|
||||||
|
func1 += ngs.CoefficientFunction((deformation, 0.0))
|
||||||
|
func0 += ngs.CoefficientFunction((deformation, 0.0))
|
||||||
|
|
||||||
|
d['show_wireframe'] = False
|
||||||
|
d['show_mesh'] = True
|
||||||
|
if order2d>0:
|
||||||
|
og = order2d
|
||||||
|
d['show_wireframe'] = True
|
||||||
|
d['show_mesh'] = True
|
||||||
|
timer2.Start()
|
||||||
|
|
||||||
|
timer3Bvals.Start()
|
||||||
|
|
||||||
|
# transform point-values to Bernsteinbasis
|
||||||
|
def Binomial(n,i): return math.factorial(n) / math.factorial(i) / math.factorial(n-i)
|
||||||
|
def Bernstein(x, i, n): return Binomial(n,i) * x**i*(1-x)**(n-i)
|
||||||
|
Bvals = ngs.Matrix(og+1,og+1)
|
||||||
|
for i in range(og+1):
|
||||||
|
for j in range(og+1):
|
||||||
|
Bvals[i,j] = Bernstein(i/og, j, og)
|
||||||
|
iBvals = Bvals.I
|
||||||
|
timer3Bvals.Stop()
|
||||||
|
# print (Bvals)
|
||||||
|
# print (iBvals)
|
||||||
|
|
||||||
|
|
||||||
|
Bezier_points = []
|
||||||
|
|
||||||
|
ipts = [(i/og,0) for i in range(og+1)] + [(0, i/og) for i in range(og+1)] + [(i/og,1.0-i/og) for i in range(og+1)]
|
||||||
|
ir_trig = ngs.IntegrationRule(ipts, [0,]*len(ipts))
|
||||||
|
ipts = [(i/og,0) for i in range(og+1)] + [(0, i/og) for i in range(og+1)] + [(i/og,1.0) for i in range(og+1)] + [(1.0, i/og) for i in range(og+1)]
|
||||||
|
ir_quad = ngs.IntegrationRule(ipts, [0,]*len(ipts))
|
||||||
|
|
||||||
|
vb = [ngs.VOL, ngs.BND][mesh.dim-2]
|
||||||
|
if region and region.VB() == vb:
|
||||||
|
vb = region
|
||||||
|
cf = func1 if draw_surf else func0
|
||||||
|
timer2map.Start()
|
||||||
|
pts = mesh.MapToAllElements({ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad}, vb)
|
||||||
|
timer2map.Stop()
|
||||||
|
pmat = cf(pts)
|
||||||
|
|
||||||
|
timermult.Start()
|
||||||
|
pmat = pmat.reshape(-1, og+1, 4)
|
||||||
|
if False:
|
||||||
|
BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1))
|
||||||
|
else:
|
||||||
|
BezierPnts = np.zeros( (og+1, pmat.shape[0], 4) )
|
||||||
|
for i in range(4):
|
||||||
|
ngsmat = ngs.Matrix(pmat[:,:,i].transpose())
|
||||||
|
BezierPnts[:,:,i] = iBvals * ngsmat
|
||||||
|
timermult.Stop()
|
||||||
|
|
||||||
|
timer2list.Start()
|
||||||
|
for i in range(og+1):
|
||||||
|
Bezier_points.append(encodeData(BezierPnts[i]))
|
||||||
|
timer2list.Stop()
|
||||||
|
|
||||||
|
d['Bezier_points'] = Bezier_points
|
||||||
|
|
||||||
|
ipts = [(i/og,0) for i in range(og+1)]
|
||||||
|
ir_seg = ngs.IntegrationRule(ipts, [0,]*len(ipts))
|
||||||
|
vb = [ngs.VOL, ngs.BND, ngs.BBND][mesh.dim-1]
|
||||||
|
if region and region.VB() == vb:
|
||||||
|
vb = region
|
||||||
|
pts = mesh.MapToAllElements(ir_seg, vb)
|
||||||
|
pmat = func0(pts)
|
||||||
|
pmat = pmat.reshape(-1, og+1, 4)
|
||||||
|
edge_data = np.tensordot(iBvals.NumPy(), pmat, axes=(1,1))
|
||||||
|
edges = []
|
||||||
|
for i in range(og+1):
|
||||||
|
edges.append(encodeData(edge_data[i]))
|
||||||
|
d['edges'] = edges
|
||||||
|
|
||||||
|
ndtrig = int((og+1)*(og+2)/2)
|
||||||
|
|
||||||
|
if og in bezier_trig_trafos.keys():
|
||||||
|
iBvals_trig = bezier_trig_trafos[og]
|
||||||
|
else:
|
||||||
|
def BernsteinTrig(x, y, i, j, n):
|
||||||
|
return math.factorial(n)/math.factorial(i)/math.factorial(j)/math.factorial(n-i-j) \
|
||||||
|
* x**i*y**j*(1-x-y)**(n-i-j)
|
||||||
|
Bvals = ngs.Matrix(ndtrig, ndtrig)
|
||||||
|
ii = 0
|
||||||
|
for ix in range(og+1):
|
||||||
|
for iy in range(og+1-ix):
|
||||||
|
jj = 0
|
||||||
|
for jx in range(og+1):
|
||||||
|
for jy in range(og+1-jx):
|
||||||
|
Bvals[ii,jj] = BernsteinTrig(ix/og, iy/og, jx, jy, og)
|
||||||
|
jj += 1
|
||||||
|
ii += 1
|
||||||
|
iBvals_trig = Bvals.I
|
||||||
|
bezier_trig_trafos[og] = iBvals_trig
|
||||||
|
|
||||||
|
|
||||||
|
# Bezier_points = [ [] for i in range(ndtrig) ]
|
||||||
|
Bezier_points = []
|
||||||
|
|
||||||
|
ipts = [(i/og,j/og) for j in range(og+1) for i in range(og+1-j)]
|
||||||
|
ir_trig = ngs.IntegrationRule(ipts, [0,]*len(ipts))
|
||||||
|
ipts = ([(i/og,j/og) for j in range(og+1) for i in range(og+1-j)] +
|
||||||
|
[(1-i/og,1-j/og) for j in range(og+1) for i in range(og+1-j)])
|
||||||
|
ir_quad = ngs.IntegrationRule(ipts, [0,]*len(ipts))
|
||||||
|
|
||||||
|
vb = [ngs.VOL, ngs.BND][mesh.dim-2]
|
||||||
|
if region and region.VB() == vb:
|
||||||
|
vb = region
|
||||||
|
pts = mesh.MapToAllElements({ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad}, vb)
|
||||||
|
|
||||||
|
pmat = ngs.CoefficientFunction( func1 if draw_surf else func0 ) (pts)
|
||||||
|
|
||||||
|
|
||||||
|
funcmin = np.min(pmat[:,3])
|
||||||
|
funcmax = np.max(pmat[:,3])
|
||||||
|
pmin = np.min(pmat[:,0:3], axis=0)
|
||||||
|
pmax = np.max(pmat[:,0:3], axis=0)
|
||||||
|
|
||||||
|
mesh_center = 0.5*(pmin+pmax)
|
||||||
|
mesh_radius = np.linalg.norm(pmax-pmin)/2
|
||||||
|
|
||||||
|
pmat = pmat.reshape(-1, len(ir_trig), 4)
|
||||||
|
|
||||||
|
BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1,1))
|
||||||
|
|
||||||
|
for i in range(ndtrig):
|
||||||
|
Bezier_points.append(encodeData(BezierPnts[i]))
|
||||||
|
|
||||||
|
|
||||||
|
d['Bezier_trig_points'] = Bezier_points
|
||||||
|
d['mesh_center'] = list(mesh_center)
|
||||||
|
d['mesh_radius'] = mesh_radius
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if func:
|
||||||
|
d['funcmin'] = funcmin
|
||||||
|
d['funcmax'] = funcmax
|
||||||
|
return d
|
||||||
|
|
||||||
|
def Draw(shape, clipping=None, js_code=None, filename=""):
|
||||||
|
# todo: also handle occ geometry, list of shapes, etc.
|
||||||
|
|
||||||
|
scene = WebGLScene(shape, clipping=clipping, on_init=js_code)
|
||||||
|
|
||||||
|
if wg._IN_IPYTHON:
|
||||||
|
if wg._IN_GOOGLE_COLAB:
|
||||||
|
from IPython.display import display, HTML
|
||||||
|
html = scene.GenerateHTML()
|
||||||
|
display(HTML(html))
|
||||||
|
else:
|
||||||
|
# render scene using widgets.DOMWidget
|
||||||
|
scene.Draw()
|
||||||
|
return scene
|
||||||
|
else:
|
||||||
|
if filename:
|
||||||
|
scene.GenerateHTML(filename=filename)
|
||||||
|
return scene
|
||||||
|
|
Loading…
Reference in New Issue
Block a user