When it comes to exporting data from a Karamba3D model to another data-format one could simply go through the object tree of the model and iterate manually over the existing entities like e.g. nodes, elements, materials, . . . . The use of a builder pattern removes some of the bureaucratic overhead involved in this approach. The script in the example “ModelExport.gh” shows how to generate an XML-file based on a given Karamba3D-model. The output consists of a string which can be streamed to a file. When opened with a web-browser a nicely formatted tree results (see fig. 2.5.1).
By inheriting from "Karamba.Exporters.ExportBuilder" and overriding "builder"-methods a builder-class can be configured to export Karamba3D-models to any format - here XML.
The corresponding source-code looks like this:
...usingSystem.Xml;usingSystem.IO;usingKaramba.Models;usingKaramba.Nodes;usingKaramba.CrossSections;usingKaramba.Elements;usingKaramba.Loads;usingKaramba.Materials;usingKaramba.Supports;usingKaramba.Geometry;...privatevoidRunScript(object Model_in,refobject XML){var model = Model_in asModel;if (model ==null) {thrownewArgumentException("The input is not of type model!"); }var builder =newBuilderXML();var director =newKaramba.Exporters.ExportDirector();director.ConstructExport(model, builder); XML =builder.getProduct();}// <Custom additional code>publicclassBuilderXML:Karamba.Exporters.ExportBuilder { // the XML documentprivateXmlDocument doc_ =newXmlDocument(); // the model inside the xml-documentprivateXmlElement model_;publicoverridevoidnewProduct() { model_ = (XmlElement) doc_.AppendChild(doc_.CreateElement("K3DModel")); }publicoverridevoidbuildMaterial(FemMaterial m,int ind) {var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("FemMaterial"));xml_node.InnerText="ind: "+ ind +":"+m.ToString(); }publicoverridevoidbuildVertex(Node v) {var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("Node"));xml_node.InnerText=v.ToString(); }publicoverridevoidbuildCroSec(CroSec crosec) {var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("CroSec"));xml_node.InnerText=crosec.ToString(); }publicoverridevoidbuildElement(ModelElement e,Model model) {var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("ModelElement"));xml_node.InnerText=e.ToString(); }publicoverridevoidbuildElementLoad(ModelElement elem,Model model) {foreach (var l inelem.Elem_loads) {var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("ElementLoad"));xml_node.InnerText=l.ToString(); } }publicoverridevoidbuildLoadCase(int lc_ind,Model model) {Vector3 g_vec =newVector3(0,0,0);foreach (GravityLoad g inmodel.gravities.Values) {if (model.lc_combinator.lc_inds(g.LcName).Contains(lc_ind)) { g_vec =g.force; }; }var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("LoadCase"));xml_node.InnerText="load-case: "+ lc_ind +" g ="+ g_vec; }publicoverridevoidbuildSupport(Support s) {var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("Support"));xml_node.InnerText=s.ToString(); }publicoverridevoidbuildPointLoad(PointLoad p) {var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("PointLoad"));xml_node.InnerText=p.ToString(); }publicoverridevoidbuildMeshLoad(MeshLoad m) {var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("MeshLoad"));xml_node.InnerText=m.ToString(); }publicstringgetProduct() {StringWriter sw =newStringWriter();XmlTextWriter tx =newXmlTextWriter(sw);doc_.WriteTo(tx);string str =sw.ToString();//return str; }}// </Custom additional code>
The first part of the script comprises the “RunScript”-method. There the “Model_in”-object gets converted to a Karamba3D-Model. In line 20 follows the creation of a builder-object which does the conversion-work. The class “BuilderXML” gets defined further below in the script. A director-object is instantiated in the next line. Its task consists of iterating over the model constituents and presenting them to the builder. Calling “ConstructExport” in line 22 initiates the creation process. Line 24 assigns the builder’s product to the output variable “XML”.
The “BuilderXML”-class derives from Karamba.Exporters.ExportBuilder and overrides some of its methods. In order to keep things simple each build-method adds a XML-node which contains the string-representation of the corresponding argument. In case of “ModelElement” the corresponding build-method does not know which type of element gets passed. Thus one has to apply pattern matching to find get the right type (e.g. “ModelBeam”, “ModelTruss”, “ModelShell” or “ModelSpring”)