diff --git a/backends/blender2.59/dbus-server.py b/backends/blender2.59/dbus-server.py index 59b1b8f..b188211 100644 --- a/backends/blender2.59/dbus-server.py +++ b/backends/blender2.59/dbus-server.py @@ -68,14 +68,6 @@ def stop(self): l.quit() return "stopped" - @mod3D_api(reference = undefined_object, length = not_zero) - def make_box(self, reference=-1, length=1, width=1, height=1): - ops.mesh.primitive_cube_add() - context.active_object.name = reference - size = (length, width, height) - ops.transform.resize(size) - return reference - @mod3D_api(reference = defined_object, frame = positive_int) def move_to(self, reference, x=None, y=None, z=None, frame=1, immediate=False): o = data.objects[reference] @@ -127,20 +119,51 @@ def set_material_property(self, reference, prop, value, immediate=True, frame=1) return reference @mod3D_api(reference = undefined_object) - def make_cone(self, reference, x=0.0, y=0.0, z=1.0, diameter=1.0, height=1.0): - ops.mesh.primitive_cone_add(radius=diameter / 2.0, depth=height) + def make_shape(self, reference, descr, length=1.0, width=1.0, height=1.0, x=0.0, y=0.0, z=1.0, extra=0.0): + if descr == "cylinder": + ops.mesh.primitive_cylinder_add() + ops.transform.resize((length, width, height)) + elif descr == "cone": + ops.mesh.primitive_cone_add() + ops.transform.resize((length, width, height)) + elif descr == "sphere": + ops.mesh.primitive_uv_sphere_add() + ops.transform.resize((length, width, height)) + elif descr == "box": + ops.mesh.primitive_cube_add() + ops.transform.resize((length, width, height)) + elif descr == "plane": + ops.mesh.primitive_cube_add() + ops.transform.resize((length, width, 0.0001)) + else: + print "shape {} not implemented".format(descr) + return reference + z_axis = Vector(0,0,1) + target = Vector(x,y,z) + q = z_axis.difference(target) + ops.transform.rotate(value=q.angle, axis=q.axis) context.active_object.name = reference return reference @mod3D_api(reference = undefined_object) - def make_sphere(self, reference, size): - ops.mesh.primitive_uv_sphere_add(size=size) - context.active_object.name = reference - return reference - - @mod3D_api(reference = undefined_object) - def make_cylinder(self, reference, x=0.0, y=0.0, z=1.0, diameter=1.0, height=1.0): - ops.mesh.primitive_cylinder_add(radius=diameter / 2.0, depth=height) + def update_shape(self, reference, descr, length=1.0, width=1.0, height=1.0, x=0.0, y=0.0, z=1.0, extra=0.0): + if descr == "cylinder": + ops.transform.resize((length, width, height)) + elif descr == "cone": + ops.transform.resize((length, width, height)) + elif descr == "sphere": + ops.transform.resize((length, width, height)) + elif descr == "box": + ops.transform.resize((length, width, height)) + elif descr == "plane": + ops.transform.resize((length, width, 0.0001)) + else: + print "shape {} not implemented".format(descr) + return reference + z_axis = Vector(0,0,1) + target = Vector(x,y,z) + q = z_axis.difference(target) + ops.transform.rotate(value=q.angle, axis=q.axis) context.active_object.name = reference return reference @@ -183,3 +206,5 @@ def rotate(self, reference, R_1_1, R_1_2, R_1_3, R_2_1,R_2_2, R_2_3, R_3_1, R_3_ name = dbus.service.BusName("de.tuberlin.uebb.modelica3d.server", session_bus) api = Modelica3DAPI(session_bus, "/de/tuberlin/uebb/modelica3d/server") l.run() + +# vim:ts=4:sw=4:expandtab diff --git a/backends/osg-gtk/python/dbus-server.py b/backends/osg-gtk/python/dbus-server.py index 4a98f62..febe32f 100644 --- a/backends/osg-gtk/python/dbus-server.py +++ b/backends/osg-gtk/python/dbus-server.py @@ -88,7 +88,7 @@ def defined_material(ref) : # Check for positive value def positive(s): return (s <= 0.0, "expected positive value") - + def positive_int(i): return (isinstance(i,int) and i >= 0, "expected positive int") @@ -106,26 +106,21 @@ def stop(self): l.quit() return "stopped" - @mod3D_api(reference = undefined_object, length = not_zero) - def make_box(self, reference, length=1, width=1, height=1, tx=0.0, ty=0.0, tz=1.0): - self.omg.proc3d_create_box(self.ctxt, c_char_p(reference), - c_double(tx), c_double(ty), c_double(tz), - c_double(width), c_double(length), c_double(height)) - return reference - - @mod3D_api(reference = undefined_object, height = not_zero, diameter = not_zero) - def make_cone(self, reference, x=0.0, y=0.0, z=1.0, diameter=1, height=5): - self.omg.proc3d_create_cone(self.ctxt, c_char_p(reference), c_double(x), c_double(y), c_double(z), c_double(height), c_double(diameter / 2.0)); + @mod3D_api(reference = undefined_object) + def make_shape(self, reference, descr, length, width, height, x, y, z, extra, immediate=False): + if (length < 0.001 or width < 0.001 or height < 0.001): return reference + print 'making shape', descr, length, width, height, x, y, z, extra + self.omg.proc3d_create_shape(self.ctxt, c_char_p(reference), c_char_p(descr), + c_double(length), c_double(width), c_double(height), + c_double(x), c_double(y), c_double(z), c_double(extra)) return reference - @mod3D_api(reference = undefined_object, size = not_zero) - def make_sphere(self, reference, size=1): - self.omg.proc3d_create_sphere(self.ctxt, c_char_p(reference), c_double(size / 2.0)); - return reference - - @mod3D_api(reference = undefined_object, height = not_zero, diameter = not_zero) - def make_cylinder(self, reference, x=0.0, y=0.0, z=1.0, diameter=1, height = 10): - self.omg.proc3d_create_cylinder(self.ctxt, c_char_p(reference), c_double(x), c_double(y), c_double(z), c_double(height), c_double(diameter / 2.0)) + @mod3D_api(reference = defined_object) + def update_shape(self, reference, descr, length, width, height, x, y, z, extra, t, immediate=False): + if (length < 0.001 or width < 0.001 or height < 0.001): return reference + self.omg.proc3d_update_shape(self.ctxt, c_char_p(reference), c_char_p(descr), + c_double(length), c_double(width), c_double(height), + c_double(x), c_double(y), c_double(z), c_double(extra), c_double(t)) return reference @mod3D_api(reference = defined_object) @@ -173,7 +168,7 @@ def rotate(self, reference, R_1_1, R_1_2, R_1_3, R_2_1, R_2_2, R_2_3, R_3_1, R_3_2, R_3_3, - t=0.0): + t=0.0, immediate=False): self.omg.proc3d_set_rotation_matrix(self.ctxt, c_char_p(reference), c_double(R_1_1), c_double(R_1_2), c_double(R_1_3), c_double(R_2_1), c_double(R_2_2), c_double(R_2_3), diff --git a/backends/osg-gtk/src/osg_interpreter.hpp b/backends/osg-gtk/src/osg_interpreter.hpp index a1f9f2f..8811dd1 100644 --- a/backends/osg-gtk/src/osg_interpreter.hpp +++ b/backends/osg-gtk/src/osg_interpreter.hpp @@ -21,6 +21,8 @@ #pragma once +#include + #include #include #include @@ -40,6 +42,7 @@ using namespace proc3d; using namespace osg; typedef std::map> t_node_cache; +typedef std::map> t_shape_cache; typedef std::map> t_material_cache; struct proc3d_osg_interpreter : boost::static_visitor<> { @@ -47,10 +50,11 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { const ref_ptr root; public: t_node_cache& node_cache; + t_shape_cache & shape_cache; t_material_cache& material_cache; - proc3d_osg_interpreter(const ref_ptr r, t_node_cache& c, t_material_cache& m) : - root(r), node_cache(c), material_cache(m) {} + proc3d_osg_interpreter(const ref_ptr r, t_node_cache& c, t_shape_cache & s, t_material_cache& m) : + root(r), node_cache(c), shape_cache(s), material_cache(m) {} void operator()(const CreateGroup& cmd) const { @@ -68,22 +72,22 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { void operator()(const ApplyMaterial& cmd) const { - // do not apply material to file objects (where target name begins with "file") - // a better idea is needed -> are the colors specified in modelica to be ignored or not? - const std::string FILE("file"); - if (cmd.name.compare(0, FILE.length(), FILE) == 0) return; + // do not apply material to file objects (where target name begins with "file") + // a better idea is needed -> are the colors specified in modelica to be ignored or not? + const std::string FILE("file"); + if (cmd.name.compare(0, FILE.length(), FILE) == 0) return; if (node_cache.find(cmd.name) == node_cache.end()) { - std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; return; } if (material_cache.find(cmd.target) == material_cache.end()) { - std::cout << "Inconsistent naming. Did not find material: " << cmd.target << std::endl; + //std::cout << "Inconsistent naming. Did not find material: " << cmd.target << std::endl; return; } - std::cout << "Apply material " << cmd.target << " on " << cmd.name << std::endl; + //std::cout << "Apply material " << cmd.target << " on " << cmd.name << std::endl; const ref_ptr mat = material_cache[cmd.target]; @@ -91,120 +95,227 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { stateSet->setAttribute(mat.get()); } - void operator()(const CreateSphere& cmd) const { - const ref_ptr shape = - new ShapeDrawable(new Sphere(Vec3(cmd.radius,0,0), cmd.radius)); - const ref_ptr geode = new Geode(); - geode->addDrawable(shape); - - const ref_ptr trans = - new PositionAttitudeTransform(); - trans->addChild(geode); - trans->setName(cmd.name); - - node_cache[cmd.name] = trans; - root->addChild(trans); - } - - void operator()(const CreateBox& cmd) const { - osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); - target.normalize(); - target *= cmd.height; - const Vec3 center = target / 2.0; - - //Rotate to target - const Vec3 z = osg::Vec3(0,0,1); - Quat q; q.makeRotate(z, target); - - const ref_ptr shape = new Box(center, cmd.width, cmd.length, cmd.height); - const ref_ptr draw = new ShapeDrawable(shape); - - const ref_ptr geode = new Geode(); - geode->addDrawable(draw); - - const ref_ptr trans = - new PositionAttitudeTransform(); - trans->addChild(geode); - trans->setName(cmd.name); - - shape->setRotation(q); - - node_cache[cmd.name] = trans; - root->addChild(trans); - } - - void operator()(const CreateCylinder& cmd) const { - osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); - target.normalize(); - target *= cmd.height; - const Vec3 center = target / 2.0; - - //Rotate to target - const Vec3 z = osg::Vec3(0,0,1); - Quat q; q.makeRotate(z, target); - - const ref_ptr shape = new Cylinder(center, cmd.radius, cmd.height); - const ref_ptr draw = new ShapeDrawable(shape); - + void operator()(const CreateShape& cmd) const { + + //std::cout + //<< "name: " << cmd.name << "\n" + //<< "descr: " << cmd.descr << "\n" + //<< "length: " << cmd.length << "\n" + //<< "width: " << cmd.width << "\n" + //<< "height: " << cmd.height << "\n" + //<< "x: " << cmd.at[0] << "\n" + //<< "y: " << cmd.at[1] << "\n" + //<< "z: " << cmd.at[2] << "\n" + //<< "extra: " << cmd.extra << "\n" + //<< std::endl; + + // generic setup + const char * descr = cmd.descr.c_str(); const ref_ptr geode = new Geode(); - geode->addDrawable(draw); - - const ref_ptr trans = + const ref_ptr shape = new PositionAttitudeTransform(); - trans->addChild(geode); - trans->setName(cmd.name); - - shape->setRotation(q); - - node_cache[cmd.name] = trans; - root->addChild(trans); - } - - void operator()(const CreateCone& cmd) const { - osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); - target.normalize(); - target *= cmd.height; - - //Rotate to target - const Vec3 z = osg::Vec3(0,0,1); - Quat q; q.makeRotate(z, target); - - const ref_ptr shape = new Cone(Vec3d(0,0,0), cmd.radius, cmd.height); - const ref_ptr draw = new ShapeDrawable(shape); - - const ref_ptr geode = new Geode(); - geode->addDrawable(draw); - + shape->addChild(geode); const ref_ptr trans = new PositionAttitudeTransform(); - trans->addChild(geode); + trans->addChild(shape); trans->setName(cmd.name); - shape->setRotation(q); + // shape specific + if (!strcmp(descr, "cylinder")) { + // create geometry + geode->addDrawable(new ShapeDrawable(new Cylinder)); + + // set size + shape->setScale(osg::Vec3(cmd.width, cmd.width, cmd.height)); + + // target vector + osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); + target.normalize(); + target *= cmd.height; + + // translate to center + shape->setPosition(target / 2.0); + + // rotate to target + const Vec3 z = osg::Vec3(0,0,1); + Quat q; q.makeRotate(z, target); + shape->setAttitude(q); + + } else if (!strcmp(descr, "cone")) { + // create geometry + geode->addDrawable(new ShapeDrawable(new Cone)); + + // set size + shape->setScale(osg::Vec3(cmd.width, cmd.width, cmd.height)); + + // target vector + osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); + target.normalize(); + target *= cmd.height; + + // rotate to target + const Vec3 z = osg::Vec3(0,0,1); + Quat q; q.makeRotate(z, target); + shape->setAttitude(q); + + } else if (!strcmp(descr, "sphere")) { + // create geometry + geode->addDrawable(new ShapeDrawable(new Sphere)); + + // translate to center + shape->setPosition(Vec3(cmd.width/2, 0, 0)); + + // null rotation + shape->setAttitude(Quat(0, Vec3(1,0,0))); + + // set size + shape->setScale(osg::Vec3(cmd.width/2, cmd.width/2, cmd.width/2)); + + } else if (!strcmp(descr, "box")) { + // create geometry + geode->addDrawable(new ShapeDrawable(new Box)); + + // set size + shape->setScale(osg::Vec3(cmd.length/2, cmd.width/2, cmd.height/2)); + + // target vector + osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); + target.normalize(); + target *= cmd.height; + + // translate to center + shape->setPosition(target / 2.0); + + // rotate to target + const Vec3 z = osg::Vec3(0,0,1); + Quat q; q.makeRotate(z, target); + shape->setAttitude(q); + + } else if (!strcmp(descr, "plane")) { + // create geometry + geode->addDrawable(new ShapeDrawable(new Box)); + + // set size + shape->setScale(osg::Vec3(cmd.length/2, cmd.width/2, 0.01)); + + // target vector + osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); + target.normalize(); + target *= cmd.height; + + // rotate to target + const Vec3 z = osg::Vec3(0,0,1); + Quat q; q.makeRotate(z, target); + shape->setAttitude(q); + + } else { + std::cerr << "shape: " << descr << " not implemented" << std::endl; + return; + } + // add to caches and scene node_cache[cmd.name] = trans; + shape_cache[cmd.name] = shape; root->addChild(trans); } - void operator()(const CreatePlane& cmd) const { - const ref_ptr shape = new Box(Vec3(0,0,0), cmd.width, cmd.length, 0.05); - const ref_ptr draw = new ShapeDrawable(shape); - - const ref_ptr geode = new Geode(); - geode->addDrawable(draw); - - const ref_ptr trans = - new PositionAttitudeTransform(); - trans->addChild(geode); - trans->setName(cmd.name); + void operator()(const UpdateShape& cmd) const { + //std::cout + //<< "name: " << cmd.name << "\n" + //<< "descr: " << cmd.descr << "\n" + //<< "time: " << cmd.time << "\n" + //<< "length: " << cmd.length << "\n" + //<< "width: " << cmd.width << "\n" + //<< "height: " << cmd.height << "\n" + //<< "x: " << cmd.at[0] << "\n" + //<< "y: " << cmd.at[1] << "\n" + //<< "z: " << cmd.at[2] << "\n" + //<< "extra: " << cmd.extra << "\n" + //<< std::endl; + + // get shape + if (shape_cache.find(cmd.name) == shape_cache.end()) { + std::cout << "Could not find shape for update shape: " << cmd.name << std::endl; + return; + } + osg::PositionAttitudeTransform * shape = shape_cache[cmd.name]; + + const char * descr = cmd.descr.c_str(); + + if (!strcmp(descr, "cylinder")) { + // set size + shape->setScale(Vec3d(cmd.width/2, cmd.width/2, cmd.length)); + + // translate to center + osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); + target.normalize(); + target *= cmd.length; + const Vec3 center = target / 2.0; + shape->setPosition(center); + + // rotate to target + const Vec3 z = osg::Vec3(0,0,1); + Quat q; q.makeRotate(z, target); + shape->setAttitude(q); + + } else if (!strcmp(descr, "cone")) { + // set size + shape->setScale(osg::Vec3(cmd.width/2, cmd.width/2, cmd.height)); + + // target vector + osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); + target.normalize(); + target *= cmd.height; + + // rotate to target + const Vec3 z = osg::Vec3(0,0,1); + Quat q; q.makeRotate(z, target); + shape->setAttitude(q); + + } else if (!strcmp(descr, "sphere")) { + // set size + shape->setScale(osg::Vec3(cmd.width/2, cmd.width/2, cmd.width/2)); + + } else if (!strcmp(descr, "box")) { + // set size + shape->setScale(osg::Vec3(cmd.length/2, cmd.width/2, cmd.height/2)); + + // target vector + osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); + target.normalize(); + target *= cmd.height; + + // translate to center + shape->setPosition(target / 2.0); + + // rotate to target + const Vec3 z = osg::Vec3(0,0,1); + Quat q; q.makeRotate(z, target); + shape->setAttitude(q); + + } else if (!strcmp(descr, "plane")) { + // set size + shape->setScale(osg::Vec3(cmd.length, cmd.width, 0.01)); + + // target vector + osg::Vec3 target = osg::Vec3(cmd.at[0], cmd.at[1], cmd.at[2]); + target.normalize(); + target *= cmd.height; + + // rotate to target + const Vec3 z = osg::Vec3(0,0,1); + Quat q; q.makeRotate(z, target); + shape->setAttitude(q); + + } else { + std::cerr << "shape: " << descr << " not implemented" << std::endl; + } - node_cache[cmd.name] = trans; - root->addChild(trans); } void operator()(const Move& cmd) const { if (node_cache.find(cmd.name) == node_cache.end()) { - std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; return; } @@ -213,7 +324,7 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { void operator()(const Scale& cmd) const { if (node_cache.find(cmd.name) == node_cache.end()) { - std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; return; } @@ -222,7 +333,7 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { void operator()(const RotateEuler& cmd) const { if (node_cache.find(cmd.name) == node_cache.end()) { - std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; return; } @@ -232,7 +343,7 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { void operator()(const RotateMatrix& cmd) const { if (node_cache.find(cmd.name) == node_cache.end()) { - std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find " << cmd.name << std::endl; return; } @@ -249,7 +360,7 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { void operator()(const SetMaterialProperty& cmd) const { if (material_cache.find(cmd.name) == material_cache.end()) { - std::cout << "Inconsistent naming. Did not find material: " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find material: " << cmd.name << std::endl; return; } //no properties defined yet ... @@ -261,17 +372,17 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { void operator()(const SetAmbientColor& cmd) const { if (material_cache.find(cmd.name) == material_cache.end()) { - std::cout << "Inconsistent naming. Did not find material: " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find material: " << cmd.name << std::endl; return; } - std::cout << "Setting ambient color on " << cmd.name << " at t= " << cmd.time << std::endl; + //std::cout << "Setting ambient color on " << cmd.name << " at t= " << cmd.time << std::endl; material_cache[cmd.name]->setAmbient(Material::FRONT, vec4_from_array(cmd.color)); } void operator()(const SetDiffuseColor& cmd) const { if (material_cache.find(cmd.name) == material_cache.end()) { - std::cout << "Inconsistent naming. Did not find material: " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find material: " << cmd.name << std::endl; return; } @@ -280,7 +391,7 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { void operator()(const SetSpecularColor& cmd) const { if (material_cache.find(cmd.name) == material_cache.end()) { - std::cout << "Inconsistent naming. Did not find material: " << cmd.name << std::endl; + //std::cout << "Inconsistent naming. Did not find material: " << cmd.name << std::endl; return; } @@ -342,4 +453,4 @@ struct proc3d_osg_interpreter : boost::static_visitor<> { } }; - +// vim:ts=2:sw=2:expandtab diff --git a/backends/osg-gtk/src/osgviewerGTK.cpp b/backends/osg-gtk/src/osgviewerGTK.cpp index 3ee5687..3f4aed8 100644 --- a/backends/osg-gtk/src/osgviewerGTK.cpp +++ b/backends/osg-gtk/src/osgviewerGTK.cpp @@ -52,6 +52,7 @@ class OSG_GTK_Mod3DViewer : public OSGGTKDrawingArea { const proc3d::animation_queue& stored_animation; proc3d::animation_queue animation; std::map> nodes; + std::map> shapes; std::map> materials; const osg::ref_ptr scene_content; const proc3d_osg_interpreter interpreter; @@ -169,7 +170,7 @@ class OSG_GTK_Mod3DViewer : public OSGGTKDrawingArea { _tid (0), stored_animation (q), scene_content(new osg::Group()), - interpreter(scene_content, nodes, materials), + interpreter(scene_content, nodes, shapes, materials), timeScaler(1.0) { scene_content->setName("root"); @@ -177,6 +178,12 @@ class OSG_GTK_Mod3DViewer : public OSGGTKDrawingArea { setSceneData(scene_content); getCamera()->setStats(new osg::Stats("omg")); + // fix clipping planes + getCamera()->setNearFarRatio(0.0000000000001f); + getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); + + // updates lighting when objects are scaled + scene_content->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); restart_animation(); } @@ -193,7 +200,7 @@ class OSG_GTK_Mod3DViewer : public OSGGTKDrawingArea { // add menu item for each object for(std::map>::iterator i = nodes.begin(); i!= nodes.end(); i++) { - std::cout << "adding menu item for node: " << i->first << std::endl; + //std::cout << "adding menu item for node: " << i->first << std::endl; GtkWidget* item = gtk_menu_item_new_with_label((i->first).c_str()); gtk_menu_shell_append(GTK_MENU_SHELL(_menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(OSG_GTK_Mod3DViewer::setFocus), this); @@ -229,13 +236,13 @@ class OSG_GTK_Mod3DViewer : public OSGGTKDrawingArea { useconds = now.tv_usec - startTime.tv_usec; currentTime = tOffset + timeScaler*(seconds + 1e-6*useconds); - // std::cout << "Update at t=" << currentTime << std::endl; + //std::cout << "Update at t=" << currentTime << std::endl; if (animation.empty()) { restart_animation(); } else { AnimOperation op = animation.top(); - // std::cout << "Anim command for t= " << proc3d::time_of(op) << std::endl; + //std::cout << "Anim command for t= " << proc3d::time_of(op) << std::endl; while (proc3d::time_of(op) <= currentTime && !animation.empty()) { boost::apply_visitor( interpreter, op ); animation.pop(); diff --git a/lib/mod3d/src/modelica/Modelica3D 3.2.1/package.mo b/lib/mod3d/src/modelica/Modelica3D 3.2.1/package.mo index c3421a8..8404d5c 100644 --- a/lib/mod3d/src/modelica/Modelica3D 3.2.1/package.mo +++ b/lib/mod3d/src/modelica/Modelica3D 3.2.1/package.mo @@ -43,7 +43,7 @@ package Modelica3D protected Message msg = Message(TARGET, OBJECT, INTERFACE, "make_material"); algorithm - setString(id,"material_" + String(modcount.increase_get(context))); + setString(id, "material_" + String(modcount.increase_get(context))); addString(msg, "reference", getString(id)); sendMessage(conn, msg); end createMaterial; @@ -64,43 +64,6 @@ package Modelica3D end applyMaterial; - function createBox - input Connection conn; - input Context context; - input Real length, width, height; - input Id id; - protected - Message msg = Message(TARGET, OBJECT, INTERFACE, "make_box"); - algorithm - setString(id,HeapString("box_" + String(modcount.increase_get(context)))); - addString(msg, "reference", getString(id)); - addReal(msg, "length", length); - addReal(msg, "width", width); - addReal(msg, "height", height); - sendMessage(conn, msg); - end createBox; - - - function createBoxAt - input Connection conn; - input Context context; - input Real length, width, height; - input Real tx,ty,tz; - input Id id; - protected - Message msg = Message(TARGET, OBJECT, INTERFACE, "make_box"); - algorithm - setString(id,"box_" + String(modcount.increase_get(context))); - addString(msg, "reference", getString(id)); - addReal(msg, "length", length); - addReal(msg, "width", width); - addReal(msg, "height", height); - addReal(msg, "tx", tx); - addReal(msg, "ty", ty); - addReal(msg, "tz", tz); - sendMessage(conn, msg); - end createBoxAt; - function loadFromFile input Connection conn; input Context context; @@ -120,96 +83,6 @@ package Modelica3D end loadFromFile; - function createSphere - input Connection conn; - input Context context; - input Real size; - input Id id; - protected - Message msg = Message(TARGET, OBJECT, INTERFACE, "make_sphere"); - algorithm - setString(id,"sphere_" + String(modcount.increase_get(context))); - addString(msg, "reference", getString(id)); - addReal(msg, "size", size); - sendMessage(conn, msg); - end createSphere; - - - function createCylinder - input Connection conn; - input Context context; - input Real height; - input Real diameter; - input Id id; - protected - Message msg = Message(TARGET, OBJECT, INTERFACE, "make_cylinder"); - algorithm - setString(id,"cylinder_" + String(modcount.increase_get(context))); - addString(msg, "reference", getString(id)); - addReal(msg, "height", height); - addReal(msg, "diameter", diameter); - sendMessage(conn, msg); - end createCylinder; - - - function createCylinderAt - input Connection conn; - input Context context; - input Real height; - input Real diameter; - input Real x,y,z; - input Id id; - protected - Message msg = Message(TARGET, OBJECT, INTERFACE, "make_cylinder"); - algorithm - setString(id,"cylinder_" + String(modcount.increase_get(context))); - addString(msg, "reference", getString(id)); - addReal(msg, "height", height); - addReal(msg, "diameter", diameter); - addReal(msg, "x", x); - addReal(msg, "y", y); - addReal(msg, "z", z); - sendMessage(conn, msg); - end createCylinderAt; - - - function createCone - input Connection conn; - input Context context; - input Real height; - input Real diameter; - input Id id; - protected - Message msg = Message(TARGET, OBJECT, INTERFACE, "make_cone"); - algorithm - setString(id,"cone_" + String(modcount.increase_get(context))); - addString(msg, "reference", getString(id)); - addReal(msg, "height", height); - addReal(msg, "diameter", diameter); - sendMessage(conn, msg); - end createCone; - - - function createConeAt - input Connection conn; - input Context context; - input Real height; - input Real diameter; - input Real x,y,z; - input Id id; - protected - Message msg = Message(TARGET, OBJECT, INTERFACE, "make_cone"); - algorithm - setString(id,"cone_" + String(modcount.increase_get(context))); - addString(msg, "reference", getString(id)); - addReal(msg, "height", height); - addReal(msg, "diameter", diameter); - addReal(msg, "x", x); - addReal(msg, "y", y); - addReal(msg, "z", z); - sendMessage(conn, msg); - end createConeAt; - function moveTo input Connection conn; @@ -282,6 +155,54 @@ package Modelica3D r := sendMessage(conn, msg); end scaleZ; + function createShape + input Connection conn; + input Context context; + input String descr; + input Real length, width, height; + input Real[3] at; + input Real extra; + input Id id; + protected + Message msg = Message(TARGET, OBJECT, INTERFACE, "make_shape"); + algorithm + setString(id, descr + "_" + String(modcount.increase_get(context))); + addString(msg, "reference", getString(id)); + addString(msg, "descr", descr); + addReal(msg, "length", length); + addReal(msg, "width", width); + addReal(msg, "height", height); + addReal(msg, "x", at[1]); + addReal(msg, "y", at[2]); + addReal(msg, "z", at[3]); + addReal(msg, "extra", extra); + sendMessage(conn, msg); + end createShape; + + function updateShape + input Connection conn; + input Context context; + input Id id; + input String descr; + input Real length, width, height; + input Real[3] at; + input Real extra; + input Real t; + protected + Message msg = Message(TARGET, OBJECT, INTERFACE, "update_shape"); + algorithm + addString(msg, "reference", getString(id)); + addString(msg, "descr", descr); + addReal(msg, "length", length); + addReal(msg, "width", width); + addReal(msg, "height", height); + addReal(msg, "x", at[1]); + addReal(msg, "y", at[2]); + addReal(msg, "z", at[3]); + addReal(msg, "extra", extra); + addReal(msg, "t", t); + sendMessage(conn, msg); + end updateShape; function setAmbientColor input Connection conn; @@ -420,59 +341,6 @@ package Modelica3D import Id = ModelicaServices.modcount.HeapString; import Modelica.Mechanics.MultiBody.Frames; - function shapeDescrTo3D - input Connection conn; - input Context context; - input String descr; - input Real length, width, height; - input Real[3] at; - input Real extra; - input Id id; - algorithm - - if (descr == "box") then - createBoxAt(conn, context, width, height, length, at[1], at[2], at[3], id); - elseif (descr == "cone") then - createConeAt(conn, context, length, width, at[1], at[2], at[3], id); - elseif (descr == "sphere") then - createSphere(conn, context, length, id); - elseif (descr == "cylinder") then - createCylinderAt(conn, context, length, width, at[1], at[2], at[3], id); - elseif (descr == "pipecylinder") then - if (Modelica.Math.isEqual(extra, 0.0)) then - createCylinderAt(conn, context, length, width, at[1], at[2], at[3], id); - else - // not yet supported - Modelica.Utilities.Streams.print("Error: Visualization of pipecylinders has not been implemented yet!"); - setString(id,"UNKNOWN"); - end if; - elseif (descr == "pipe") then - if (Modelica.Math.isEqual(extra, 0.0)) then - createCylinderAt(conn, context, length, width, at[1], at[2], at[3], id); - else - // not yet supported - Modelica.Utilities.Streams.print("Error: Visualization of pipes has not been implemented yet!"); - setString(id,"UNKNOWN"); - end if; - elseif (descr == "beam") then - // not yet supported - Modelica.Utilities.Streams.print("Error: Visualization of beams has not been implemented yet!"); - setString(id,"UNKNOWN"); - elseif (descr == "gearwheel") then - // not yet supported - Modelica.Utilities.Streams.print("Error: Visualization of gearwheels has not been implemented yet!"); - setString(id,"UNKNOWN"); - elseif (descr == "spring") then - // not yet supported - Modelica.Utilities.Streams.print("Error: Visualization of springs has not been implemented yet!"); - setString(id,"UNKNOWN"); - else - // assume it is a filename - loadFromFile(conn, context, Modelica.Utilities.Files.fullPathName(ModelicaServices.ExternalReferences.loadResource(descr)), at[1], at[2], at[3], id); - end if; - - end shapeDescrTo3D; - outer Controller m3d_control; Id id = Id(""); @@ -504,6 +372,10 @@ package Modelica3D res := moveTo(m3d_control.conn, m3d_control.context, id, pos, time); end if; + // check for shape change, and update if necessary + // TODO: do check, for shape update instead of moved + updateShape(m3d_control.conn, m3d_control.context, id, shapeType, length, width, height, lengthDirection, extra, time); + end when; if modcount.get(initContext) <> 1 then @@ -514,7 +386,7 @@ package Modelica3D Modelica.Utilities.Streams.print( "height = " + String(height)); - shapeDescrTo3D(m3d_control.conn, m3d_control.context, shapeType, length, width, height, lengthDirection, extra, id); + createShape(m3d_control.conn, m3d_control.context, shapeType, length, width, height, lengthDirection, extra, id); createMaterial(m3d_control.conn, m3d_control.context, mat); setAmbientColor(m3d_control.conn, m3d_control.context, mat, color[1] / 255, color[2] / 255, color[3] / 255, 1.0, time); setSpecularColor(m3d_control.conn, m3d_control.context, mat, specularCoefficient * (color[1] / 255), diff --git a/lib/proc3d/src/operations.hpp b/lib/proc3d/src/operations.hpp index bf3fdac..017f2e7 100644 --- a/lib/proc3d/src/operations.hpp +++ b/lib/proc3d/src/operations.hpp @@ -38,6 +38,16 @@ namespace proc3d { struct CreateGroup : ObjectOperation { CreateGroup(const std::string& name) : ObjectOperation(name) {} }; + + struct CreateShape : ObjectOperation { + CreateShape(const std::string& name, const std::string& descr, const double l, const double w, const double h, const double extra, const array& a) : ObjectOperation(name), descr(descr), length(l), width(w), height(h), extra(extra), at(a) {} + std::string descr; + double length; + double width; + double height; + double extra; + array at; + }; struct LoadObject : ObjectOperation { LoadObject(const std::string& name, const std::string& f, const array& a) : ObjectOperation(name), fileName(f), at(a) {} @@ -124,6 +134,16 @@ namespace proc3d { double value; }; + struct UpdateShape : DeltaOperation { + UpdateShape(const std::string& name, const double t, const std::string& descr, const double l, const double w, const double h, const double extra, const array& a) : DeltaOperation(name, t), descr(descr), length(l), width(w), height(h), extra(extra), at(a) {} + std::string descr; + double length; + double width; + double height; + double extra; + array at; + }; + struct SetAmbientColor : DeltaOperation { SetAmbientColor(const std::string& name, const double t, const double r, const double g, const double b, const double a) : @@ -145,11 +165,10 @@ namespace proc3d { array color; }; - typedef variant SetupOperation; + typedef variant SetupOperation; typedef variant AnimOperation; } diff --git a/lib/proc3d/src/proc3d.cpp b/lib/proc3d/src/proc3d.cpp index b84dbe3..4025723 100644 --- a/lib/proc3d/src/proc3d.cpp +++ b/lib/proc3d/src/proc3d.cpp @@ -54,6 +54,13 @@ namespace proc3d { getContext(context)->setupOps.push(LoadObject(name, filename, arr)); } + void proc3d_create_shape(void* context, const char* name, const char * descr, + const double length, const double width, const double height, + const double x, const double y, const double z, + const double extra) { + getContext(context)->setupOps.push(CreateShape{name, descr, length, width, height, extra, boost::array{x,y,z}}); + } + void proc3d_create_group(void* context, const char* name) { getContext(context)->setupOps.push(CreateGroup(name)); } @@ -62,31 +69,6 @@ namespace proc3d { getContext(context)->setupOps.push(CreateMaterial(name)); } - void proc3d_create_sphere(void* context, const char* name, const double radius) { - getContext(context)->setupOps.push(CreateSphere(name, radius)); - } - - void proc3d_create_box(void* context, const char* name, - const double x, const double y, const double z, - const double width, const double length, const double height) { - boost::array arr = {x,y,z}; - getContext(context)->setupOps.push(CreateBox(name, width, length, height, arr)); - } - - void proc3d_create_plane(void* context, const char* name, const double width, const double length) { - getContext(context)->setupOps.push(CreatePlane(name, width, length)); - } - - void proc3d_create_cylinder(void* context, const char* name, const double x, const double y, const double z, const double height, const double radius) { - boost::array arr = {x,y,z}; - CreateCylinder cylinder = CreateCylinder(name, radius, height, arr); - getContext(context)->setupOps.push(cylinder); - } - - void proc3d_create_cone(void* context, const char* name, const double x, const double y, const double z, const double height, const double radius) { - boost::array arr = {x,y,z}; - getContext(context)->setupOps.push(CreateCone(name, radius, height, arr)); - } void proc3d_add_to_group(void* context, const char* name, const char* target) { getContext(context)->setupOps.push(AddToGroup(name, target)); @@ -128,6 +110,13 @@ namespace proc3d { getContext(context)->deltaOps.push(SetMaterialProperty(name, time, property, value)); } + void proc3d_update_shape(void* context, const char* name, const char * descr, + const double length, const double width, const double height, + const double x, const double y, const double z, + const double extra, const double time) { + getContext(context)->deltaOps.push(UpdateShape{name, time, descr, length, width, height, extra, boost::array{x,y,z}}); + } + void proc3d_set_ambient_color(void* context, const char* name, const double r, const double g, const double b, const double a, const double time) { getContext(context)->deltaOps.push(SetAmbientColor(name, time, r, g, b, a)); } diff --git a/lib/proc3d/src/proc3d.hpp b/lib/proc3d/src/proc3d.hpp index b2785a9..a96f24e 100644 --- a/lib/proc3d/src/proc3d.hpp +++ b/lib/proc3d/src/proc3d.hpp @@ -36,27 +36,16 @@ extern "C" { /* setup ops */ void proc3d_load_object(void* context, const char* name, const char* filename, const double x, const double y, const double z); + + void proc3d_create_shape(void* context, const char* name, const char * descr, + const double length, const double width, const double height, + const double x, const double y, const double z, + const double extra); void proc3d_create_group(void* context, const char* name); void proc3d_create_material(void* context, const char* name, const double r, const double g, const double b, const double a); - void proc3d_create_sphere(void* context, const char* name, const double radius); - - void proc3d_create_box(void* context, const char* name, - const double tx, const double ty, const double tz, - const double width, const double length, const double height); - - void proc3d_create_plane(void* context, const char* name, const double width, const double length); - - void proc3d_create_cylinder(void* context, const char* name, - const double tx, const double ty, const double tz, - const double height, const double radius); - - void proc3d_create_cone(void* context, const char* name, - const double tx, const double ty, const double tz, - const double height, const double radius); - void proc3d_add_to_group(void* context, const char* name, const char* target); void proc3d_apply_material(void* context, const char* name, const char* target); @@ -77,6 +66,11 @@ extern "C" { void proc3d_set_material_property(void* context, const char* name, const char* property, const double value, const double time); + void proc3d_update_shape(void* context, const char* name, const char * descr, + const double length, const double width, const double height, + const double x, const double y, const double z, + const double extra, const double time); + /* coloring */ void proc3d_set_ambient_color(void* context, const char* name, const double r, const double g, const double b, const double a, const double time);