Archive for the ‘scripting’ Category

B-processor – eCAADe 2011, Ljubljana

Monday, November 28th, 2011

Simulation Design Tools

Using Parametric Building Information Modeling and Physical Simulation for Form Finding of Double Curved Surfaces.

Sebastian Gmelin1, Kristian Agger2, Michael Henry Lassen3

1,2Aarhus School of Architecture, Denmark, 3Alexandra Institute, Denmark

1,2,3http://www.B-processor.dk, 1,2http://www.aarch.dk, 1http://www.gmelin.li, 3http://www.alexandra.dk

1sebastian@gmelin.li, sebastian.gmelin@aarch.dk, 2kristian.agger@aarch.dk, 3henryml@cs.au.dk

Abstract. Parametric modeling is a powerful tool to create variations of a design following specified criteria. Physical modeling provides flexible relationships between design elements and can simulate the behavior of hanging chain models. Building Information Modeling can contain geometry and design properties and relations. In this paper it is proposed to join all three to create a Simulation Design Tool that allows the intuitive creation of double curved surfaces which follow the rules of funicular systems (Figure 1). This tool is implemented in B-processor, open-source Building Information Modeling software to bridge the break that occurs when moving from a design software package to Building Information Modeling. It is shown how the tool balances intuitive sculpting and accurate simulation and how the user can interact to mediate different design requirements.

Keywords. Form Finding; Parametric Building Information Modeling; B-processor; Particle Spring System; Grid Shell.

Figure 1

Figure 1
Shell Structure created in B-processor using Physical Simulation Design Tools

Introduction

Ambitious architectural design often relies on computational technologies these days. Parametric design and freeform surface modeling tools allow the creation of complex geometries that challenge construction methods. The logistics of these kinds of projects can become very sophisticated. The work effort and the process of translating geometry into shop drawings, producing construction elements and assembling them on site is multiplied by the number of different pieces and the variation of elements. Complexity becomes so high that consultants and construction companies specialize in these projects and support architects and engineers.

To handle such projects, drawings and specifications are complemented with parts schedules, CNC production code, parts labeling, position tags and special assembly strategies. To manage the variety of elements or minimize the variation in an optimization phase, these documents are usually created from parametric 3D models, which are highly specialized Building Information Models.

This is interesting because BIM technologies and software are usually not considered to be design tools. More general tools, often not even particular (architectural) CAD software is used to generate shape. The desire for freedom and flexibility is driving the design phase, while full control and precision of this design is the ultimate wish before going on site. These two extremes seem to split the traditional gradual workflow in architecture, starting from a first sketch until the creation of construction and shop drawings. The advantage of a smooth workflow is obvious, when (for any reason) the design or parts of it need to change. If the design model is not linked to the information model properly, this change might be laborious work.

The second aspect of this split is the question of constructability and economy of design. Both can only be answered with enough information at hand, meaning when a BIM model is developed. Minimizing the variation of elements, simplifying and optimizing the shape towards a specific construction method might only be done with the help of a parametric model that contains enough information about this construction. Of course these phases can be linked and a parametric setup can use a design surface as an input parameter, but these solutions are currently special answers to unique problems. It is also difficult to link the design back to the outcomes of an optimization result.

It is suggested to try using a Building Information Modeling environment for the design of complex geometries; bundling design, optimization and information phases to grow and refine shapes with the addition of detail and construction. The requirement of such software is the combination of flexibility and accuracy. While a design develops, information is added continuously, both manually and automatically; aspects of a design inform each other.

Simulation Design Tools

‘The concept of Building Information Modeling is to build a building virtually, prior to building it physically, in order to work out problems , and simulate and analyze potential impacts’ (Olcay 2010) . Pursuing the idea above, these results should not only be used to check but also re-inform the design. Instead of defining an iterative process of designing, analyzing, re-designing and re-analyzing, it is proposed to create a combination of design and analysis: simulation design tools. Simulation design uses the object property tags, meaning Building Information, to re-inform design tools. The designer works intuitively and creates desired shapes while a simulation or analysis is run in parallel processing these parameters. The tool balances user input against simulation results. Many different simulations can be considered for such tools: structural performance, thermal analysis or self shading studies, acoustical performance of spaces, or spatial relationships of rooms. It could also be imagined to use security simulations, crowd control or building sensor positioning as a simulation driver and of course combinations of these.

To achieve this, any simulation algorithm needs to be simple enough to run at high speed not to compromise the intuitive feel to the user. At the same time it has to be precise enough to create exploitable information. This choice between intuition and precision has to be answered for each individual tool. Most likely such simulation design tool will not meet the expectations of relevant specialized analysis software.

Common surface modeling tools translate user input directly into change of geometry. Moving its control points affects a B-Spline surface directly. This would contradict the idea of simulation design. Instead of changing geometry, the designer changes parameters of the simulation. This does not necessarily mean that only number values can be changed to modify a shape. To develop tools giving the impression of sculpting a shape while actually changing simulation properties is important to make the idea successful. Examples of how this could be implemented for a specific case will be shown later in this paper.

The result of this process is not only geometrical shape but also attached information. Both are directly created from the simulation and therefore updated when the shape is changed again. It is an important aspect of this process that information is not added separately in an additional step. In contrary: geometry and information form a unity and are created together. They are not just linked; they interact and ideally contain objective parameters which can help to proceed the design development.

This should not be mistaken for building components that can be placed in many BIM software packages. Those components are ready-made parametric building parts also containing geometry and relevant information. They can be modified to adopt different situations. Simulation design however does not aim to create a complete building or building-part in one step. It just tries to solve one design criterion with its related analytical aspect. The outcome might be a construction component but could as well be much more abstract: a form that maximizes views and minimizes shade, a shape that creates good acoustics or performs well structurally. Information stored in such a model is therefore not only describing the final design but also criteria that were chosen to make a design decision.

B-processor – Building Information Modeling

B-processor [3] forms the framework for the project. It is open-source BIM software currently being developed at the Aarhus School of Architecture in collaboration with the Alexandra Institute (Agger, Lassen, Knudsen, Borup, Rimestad, Norholdt, Bramsen, 2007). This lightweight CAD environment allows simple modeling in the style of Google’s Sketch-up.

B-processor translates Building Information Modeling very literally. It allows the creation of geometric 3d models and to attach information properties to its building objects. These are related and can refer to each other. In B-processor, building objects are organized in spaces. Those can be functional or constructional and have references to geometrical elements describing the shape of the space. Spaces hold properties: values, descriptions and classifications. Relations between spaces are solved automatically when spaces share a surface. To describe abstract parts of a design, like grids, guidelines, etc, an additional element was introduced: a B-Net. It is also a space that contains faces, lines and vertices but it is not taken into account when calculating relationships or schedules. This simplistic approach and the flexible architecture of B-processor allow design modeling as well as information modeling. (Figure 2).

The essential aspect of B-processor is its open-source license. This is a possible answer to the problem of compatibility of different software packages and file formats. The more information a Building Model contains, the more difficult it becomes to exchange its data. The idea is to allow users to modify the software to their needs. Data created in B-processor will never be lost, because the software is free and everybody involved in a project can use it without purchasing expensive licenses.

 

Figure 2
Model of the Ruin Hall in Kolding, created in B-processor

In a first phase of this research project, parametric objects were integrated in B-processor. They form the base for any simulation design tool as envisaged. Desired strategies depend on flexibility of geometry, constraints and dependencies. The kernel of the software was changed to allow any object drawn to become parametric by attaching scripts to it. Their parameters can be numerical or graphical, like grids or points. The information tags of an object can be used as parametric properties. There is no difference between information that is added manually or automatically by a tool and both can be used to inform the design through simulation tools.

Example – Physical Simulation Tool

As a first example and to challenge the above ideas, physical simulation was implemented in B-processor. As shown by Axel Kilian and John Ochsendorf (2005), particle-spring systems can be used to simulate hanging chain models. The shape of hanging chains represents so called funicular forms of tension and can be inverted to create pure compression structures. Many designers experimented with this technique: Gaudi, Heinz Isler and Frei Otto for example. Rebuilding Gaudi’s hanging model of Colonia Güell (Figure 3), Frei Otto (1989) and his team showed how laborious the creation of such a physical model is. The complexity of this process and of the resulting shapes makes it a valid case for a computational approach. Following Axel Kilian’s research, a tool is developed that uses a particle-spring system based on a Verlet algorithm, solving Newton’s laws of motion for a number of particles reacting to forces and moving in space.

Figure 3
Hanging Model of Colonia Güell, Gaudi, source: http://www.rolfdieternill.de/pictures/tragwerkslehre082_Page_3.jpg

Different forces act on each particle: gravity, forces of connected springs, damping forces and potentially more. These forces accelerate the particle taking its mass into account and following the equation (1). The movement of particles is calculated for a time step using equations (2) and (3). The Verlet algorithm combines these laws into one equation (4) [1].

Acceleration = Force / Mass (1)

ΔVelocity = ΔTime Acceleration (2)

ΔDistance = Velocity ∙ ΔTime (3)

ΔDistance = Velocity ∙ ΔTime + 0.5 ∙ Acceleration ∙ ΔTime2 (4)

To create such a system, the user draws any B-Net in B-processor. A “physics system” is then attached to the geometry. It automatically generates particles from all vertices and springs from all edges. Global parameters define the behavior of the simulation. To simplify the workflow, they are applied to all elements. The user can choose to change these settings locally, though, if desired. These parameters are gravity, mass, spring constant and spring equilibrium length and are used to calculate the forces acting on particles (5) (6).

Gravity Force = Mass ∙ Gravity (5)

Spring Force = -Spring Constant ∙ (Spring Length – Equilibrium Length) (6)

When starting the simulation, the particles begin to move and to deform a copy of the original B-Net. If gravity is defined other than 0, the particles are accelerated along the negative Z-axis resulting in a tension form. This can be easily reverted by applying a positive gravity that pulls the particles upwards. To prevent the whole system from moving, single vertices can be defined as fix points. The movement of particles stretches the springs until their force is strong enough to bring the system to equilibrium. The user has several possibilities to interact while the simulation is running in order to control and modify form:

  1. 1. Modifying the original, underlying b-Net: A change in the original geometry modifies the properties of the physics system accordingly. Increasing or decreasing the length of an edge results in a corresponding change of the relevant springs’ equilibrium lengths
  2. 2. Moving fix points: The positions of fix points are constantly tracked and updated. When a fix point is moved, the according point of the physics system is dragged to follow it.
  3. 3. Changing global parameters: a change of gravity, mass or global spring constant is an easy way to control the dilation of the system and the resulting curvature.
  4. 4. Changing parameters locally: Selecting an edge of the design shape allows the user to change the spring parameters for this single edge. Increasing or decreasing its spring constant or equilibrium length gives control over its stretching behavior making it stiffer or more flexible. Selecting a vertex allows the changing of its related particle’s mass.

Figure 4
Creation and Modification of a Funicular Shape

To enhance the intuitive feel, sculpting tools were implemented that allow modifying the shape locally through mouse input. Choosing such a tool, the mouse pointer becomes a “brush” that defines an area affecting the change. The user selects and clicks on parts of the geometry to change them. Selecting only a vertex, results in a very local change while selecting faces affects a wider area of the form. The tool translates the user’s input into modification of parameters. It can therefore not result in an immediate change of geometry. In fact, the user outweighs the equilibrium and the particles will move again until reaching a new state of balanced forces. Two different sculpting tools were created to illustrate this.

  1. 1. Changing the equilibrium length: With this tool, mouse input actually results in a change of the length a spring tries to reach. The user can relax or tension the shape locally, having the impression of pulling or pushing a surface. Translating this back to a physical hanging chain model, where the springs are actually chains or ropes and particles are represented by weights hung to them, this would mean a change to the length of rope between to weights. In the simulation, this connection is not subdivided and stays straight. It could be considered as a system of adequately stiff sticks that are flexibly connected to each other.
  2. 2. Modifying particle masses: Similarly to the above tool, the user changes the shape locally. Instead of modifying the springs, the tool changes the mass of particles. While increasing or decreasing that property, the impression of pulling or pushing the surface is generated. Looking at the physical hanging chain model, this can be regarded as changing the weights hung to the chains without changing their geometrical relations.

The flexible interaction of the user causes a diversion from an optimal structural solution. The advantage of using a simulation tool to mediate different requirements is that user input and computational analysis are in constant dialogue. The shape adapts automatically to parameter modification and local changes are built into the system as a whole. Because it is a flexible shape that can constantly change, more requirements can easily be assigned to it as long as they can be expressed by forces acting on particles. Additional demands might be the optimization of faces regarding similarity, planarity or rectangularity. Inspired by the work of Daniel Piker who developed the physics plug-in “kangaroo” for Rhino with Grasshopper [2], these design parameters were implemented in the tool. They all use the faces of the underlying B-Net to assign relevant forces to the particles linked to those faces’ vertices. The following forces can be assigned to the system:

  1. 1. Equal face edges: Additional springs are assigned to the face’s edges. Their equilibrium length is defined as the average edge length. They act in parallel to existing springs, enforcing or contradicting them. Triangles try to become equilateral and quadrilateral shapes try to become rhomboids.
  2. 2. Equal face diagonal: This is similar to the equal edges. Springs are assigned to the diagonally opposite particles of quadrilateral shapes. These two springs try to achieve the same average equilibrium length, transforming irregular quads towards trapezoidal shapes.
  3. 3. Face rectangularity: This is actually not a single parameter but rather a combination of 1. and 2. A quadrilateral shape with even edge length and both diagonals being the same length is a square. As the forces are keeping the system flexible the resulting shapes become more rectangular.
  4. 4. Face planarity: For each face of more than three vertices, an average plane is calculated from all vertices. A force is applied to each particle of the face dragging it perpendicularly towards this average plane.

It is most unlikely that all these demands, when applied, are being fulfilled perfectly. Depending on the form, the requirements of similar, regular and planar shapes can only be reached to certain extent while compromising the original hanging form. By changing the strength of relevant forces, the user chooses how to weight different parameters. Assessing a parameter as very strong, compromises other forces and their related requirements. It is left to the designer to mediate all demands.

Figure 5
Applying Additional Requirements as Forces to the Form

The tool does not only create a geometric shape but also stores all information used to come to it as property tags linked to the single entities of the form. Vertices remember their mass, for example, and edges maintain all information on their related spring: length, equilibrium and spring constant.

This combination of geometry and information can drive the next design step. The 3D model becomes an interlinked parametric Building Information Model.

Parametric Building Information Modeling

Before turning any form created with the above method into detailed construction, a volumetric construction space has to be generated from the design surface. A second tool uses geometry and forces created in the first step to automate this process. It thickens the surface unevenly and in relation to the spring forces acting in the edges. This should not be confused with a structural analysis arriving at specific sections for structural members. It is a relative assessment, assuming only that springs that are stretched more from their equilibrium than others are strained more. For the maximum and the minimum spring force, a thickness is assigned and interpolated linearly:

  1. 1. The maximum and the minimum spring force are searched by checking all edges of the system.
  2. 2. All spring forces are interpolated linearly to values from 0 (minimum force) to 1 (maximum force)
  3. 3. For each vertex the average spring force of all connected edges is calculated.
  4. 4. From the surrounding surfaces, the average normal is calculated for each vertex.
  5. 5. The vertices are moved in direction of their normal and opposite. The translation distance for each direction is calculated using equation (7).
  6. 6. The offset vertices are reconnected to create faces enclosing the construction space volume.

Offset = 0.5 ∙ (min. Offset + Force Interpolation ∙ (max. Offset – min. Offset)) (7)

Figure 6
Extrusion of the Hanging Shape in Relation to the Inherited Forces of the Springs

Two options of the offset are created: a shell and a grid-shell version. Because of the non-parallel offset, the faces are not necessarily planar. This can be solved by re-using the physical simulation tool. Setting gravity to 0 and defining the springs’ equilibrium as the actual length of the edges, planarity can be assigned as a single requirement.

Conclusions

The research on simulation design tools is still in its beginning. Combining the ability of Building Information Modeling to link geometric 3D data to any additional information with the flexibility of parametric modeling and the analytical objectivity of simulation might be a powerful strategy for building design. It will be interesting and necessary to develop and test other simulations for such tools. Ideally those tools are:

  1. 1. Intuitive – they must work as design tools and allow the user to mediate parameters.
  2. 2. Simple – no extensive specialist knowledge should be needed to use the tool.
  3. 3. Precise – Simulation results need to be so accurate that they improve the design by objective measure.
  4. 4. Neat – any created data must be organized and linked.

Looking at Building Information Modeling as a concept of ‘management of information and the complex relationships between (…) resources’ (Jernigan 2007) rather than restricting software solutions, allows its use for design tasks in a very sophisticated manner and helps to integrate, use and maintain design-relevant data.

For the demonstrated physics simulation and the resulting shapes a proof of the structural performance has to be carried out. This is also an opportunity to develop a link to structural analysis software and to research how simulation design tools and analysis software could communicate and how this could be integrated into the workflow. This study should be completed by adding the possibility to create a more detailed 3D model of a specific construction method, a concrete shell or a grid-shell construction.

References

Agger, K, Lassen, M, Knudsen, N, Borup, R, Rimestad, J, Norholdt, P and Bramsen, N 2007, ‘B-processor -building information design and management’, Predicting the Future, Proceed­ings of the 25th eCAADe Conference, pp. 43–50.

 

Jernigan, FE 2007, BIG BIM little bim, the practical approach to building information modeling, 4Site Press, Salisbury, Maryland.

 

Kilian, A, Ochsendorf, J 2005, ‘Particle-spring systems for structural form finding’, Journal for the international Association for shell and spatial structures, IASS, vol. 46.

 

Olcay, Ç 2010, ‘A review of Building Information Modelling Tools from an Architectural Design Perspective, in J. Underwood and U. Isikdag (eds), Handbook of research on Building Information Modeling and Construction Informatics, Hershey, New York.

 

Otto, F (ed.) 1989, The Model, Information of the Institute of Lightweight Structures (IL) No. 34, Karl Krämer Verlag, Stuttgart.

 

[1] http://www.lonesock.net/article/verlet.html.

[2] http://spacesymmetrystructure.wordpress.com/2010/01/21/kangaroo/.

[3] http://www.B-processor.dk.

 

Share

Morphogenetic Studio at Aarhus School of Architecture 2010-2011

Saturday, January 29th, 2011

Morphogenetic Studio is an experimental investigation of form generating processes through digital as well as analogue tools. The studio takes its starting point in an exploration of how relations between the general and the specific might be challenged by digital design techniques. Architects have of course always been interested in how general principles could be unfolded in specific design solutions informed by specific contextual conditions, but digital tools offer new ways of investigating these questions through the use of scripting and parametrically controlled models.  Digital models also offer new ways of linking design and realisation processes, which is another core interest of the studio. Morphogenetic Studio investigates these questions with an emphasis on spatial and tectonic potentials and possibilities.

 The studio is based on an integration of architectural teaching and research in the field of digital tectonics and algorithmic design.  The goal is to create an environment that is rooted in specific research subjects and which can generate products that reflect the research and at the same time can become a part of it.

Final installations

101015-London-3

101015-London-3

101015-London-3

101015-London-3

101015-London-3

Exhibition and Presentation

101015-London-3

101015-London-3

101015-London-3

 

 Final books and videos 

 
.interference by Bjarke Schødt, Mathias Meldgaard, Thomas Bang & Troels Holm | Make Your Own Book

 

 
MORPHOGENESIS OF ANT SWARM INTELLIGENCE by Christine Hauge Ringsmose, Agnija Rubene, Mikkel Horsbøl Lauridsen & Tobias Theil Konishi | Make Your Own Book

 

Morphogenesis Of Ant Swarm Intelligence from Tobias Theil Konishi on Vimeo.

Morphogenetic Studio // Cell Structures by Kristoffer Rauff, Lars Borgen, Annica Carina Tomasdotter Ekdahl, Anne Winther Worm | Make Your Own Book
 

Students:

  • Lars Borgen,
  • Annica Carina Tomasdotter Ekdahl,
  • Kristoffer Rauff,
  • Anne Winther Worm,
  • Troels Holm,
  • Thomas Bang Madsen,
  • Mathias Meldgaard,
  • Bjarke Lehmann Schødt
  • Nikolaj Bogensee Johansen,
  • Ragnar Zachariasen,
  • Tatiana Mukhina
  • Tobias Theil Konishi,
  • Mikkel Horsbøl Lauridsen,
  • Christine Hauge Ringsmose,
  • Agnija Rubene
  • Anita Vårbo Berglund,
  • Pelle Hviid Andersen,
  • Mateusz Bartczak

 

Teachers: 

  • Claus Peder Pedersen,
  • Niels Martin Larsen,
  • Sebastian Gmelin
Share

Joint Workshop AA London AAA Arhus

Monday, October 18th, 2010

Tutors: Robert Stuart-Smith, Knut Brunier, Niels Martin Larsen, Sebastian Gmelin
Rhino scripting, laser cutting

101015-London-3

101015-London-4

101015-London-5

101015-London-6

101015-London-7

Share

introduction to processing (scripting)

Tuesday, September 28th, 2010

www.processing.org

Processing Introduction Slide 01

Processing Introduction Slide 02

Processing Introduction Slide 03

Processing Introduction Slide 04

Processing Introduction Slide 05

Processing Introduction Slide 06

Processing Introduction Slide 07

Processing Introduction Slide 08

Processing Introduction Slide 09

Processing Introduction Slide 10

Processing Introduction Slide 11

Processing Introduction Slide 12

Processing Introduction Slide 13

Processing Introduction Slide 14

Processing Introduction Slide 15

Processing Introduction Slide 16

Processing Introduction Slide 17

Processing Introduction Slide 18

Processing Introduction Slide 19

Processing Introduction Slide20

Processing Introduction Slide 21

Processing Introduction Slide 22

Processing Introduction Slide 23

Processing Introduction Slide 24

Processing Introduction Slide 25

Processing Introduction Slide 26

Processing Introduction Slide 27

Processing Introduction Slide 28

Processing Introduction Slide 29

Share

Commit changes to sourceforge project code

Monday, May 24th, 2010
  1. In Eclipse, right-click on the main project folder and chose >team< … >update< in the context menu. This will upload changes other users made into your local code copy.
    step 01
  2. Start Cygwin shell, and direct to your workspace folder
    1. c:
    2. step 02

    3. cd Users/[…]/workspace/build
  3. run the batch build command “./build.sh clean dist”
  4. step 03
    step 04

  5. In Eclipse, right/click on the main project folder and chose >refresh< in the context menu.
  6. step 05

  7. Chose >Project< in the main menu bar and >clean< the project
  8. step-06

  9. Right-click on the main project folder (or changed folder) and chose >team< … >commit< to commit your changes to the server copy of the code.
  10. step-07

Share

Uniform Nonrational B-Splines in B-Processor

Tuesday, May 4th, 2010

Implementation in B-Processor / Java:
public static class UniformNonrationalBSpline extends Command {
  private Space net;
  /**
   * Constructs a frame command
   * @param net Space
   */
  public UniformNonrationalBSpline(Space net) {
    this.net = net;   
    parameters.put(“subdivisions”, 5.0);
    parameters.put(“UNRBSname”, “Unifrom Nonrational BSpline”);
  }
  /**
   *
{@inheritDoc}
   */
  public String title() {
    return “Unifrom Nonrational BSpline”;
  }
  //bring edges in order
  public static List<Edge> order(List<Edge> edges) {
      LinkedList<Edge> ordered = new LinkedList();
      if (edges.size() > 0) {
       Edge first = edges.get(0);
          ordered.add(first);
          edges.remove(0);
          while (edges.size()>0) {
           for (int i = 0; i < edges.size(); i++) {
            search:
            if (edges.get(i).contains(ordered.get(ordered.size()-1).to)) {
             //check direction
             if (!edges.get(i).from.equals(ordered.get(ordered.size()-1).to)) {
              Vertex temp = edges.get(i).to;
              edges.get(i).to = edges.get(i).from;
              edges.get(i).from = temp;
             }
             //add at end of Linked list
             ordered.add(edges.get(i));
             edges.remove(i);
             break search;
            } else if (edges.get(i).contains(ordered.get(0).from)) {
           //check direction
             if (!edges.get(i).to.equals(ordered.get(ordered.size()-1).from)) {
              Vertex temp = edges.get(i).to;
              edges.get(i).to = edges.get(i).from;
              edges.get(i).from = temp;
             }
             // add at beginning of Linked List
             ordered.add(0, edges.get(i));
             edges.remove(i);
             break search;
            }
           }
          }
      }
      return ordered;
    }
 
  public Vertex unrbsCalc(List<Vertex> gConst, double t) {
   Vertex blend = new Vertex(0,0,0);
   if (gConst.size()==4) {
    double[] tempCalc = new double[4];
    tempCalc[0] = ((1-t)*(1-t)*(1-t))/6;
    tempCalc[1] = (3*t*t*t-6*t*t+4)/6;
    tempCalc[2] = (-3*t*t*t+3*t*t+3*t+1)/6;
    tempCalc[3] = (t*t*t)/6;
    for (int i=0; i<=3; i++) {
     blend.x = blend.x + tempCalc[i]*gConst.get(i).x;
     blend.y = blend.y + tempCalc[i]*gConst.get(i).y;
     blend.z = blend.z + tempCalc[i]*gConst.get(i).z;
    }
    System.out.println(blend.x);
   }
 return blend;
  }
  /** {@inheritDoc} */
  @Override
  public void evaluate() {
    String UNRBSname = (String) parameters.get(“UNRBSname”);
    double subdiv = parameters.getDouble(“subdivisions”);
   
    List<Vertex> vertices = new ArrayList(net.getVertices());
    List<Edge> edges = new ArrayList(net.getEdges());
    List<Vertex> orderPoints = new ArrayList();
    List<Vertex> curvePoints = new LinkedList();
    if (vertices.size()>=3) {
     LinkedList<Edge> nEdges = new LinkedList();
     nEdges = (LinkedList) order(edges);
     // write into List
     for (int i=0; i<nEdges.size(); i++) {
      orderPoints.add(nEdges.get(i).from);
     }
     orderPoints.add(nEdges.get(nEdges.size()-1).to);
     // make Spline go through endpoints
     for (int i=0; i<=2; i++) {
      orderPoints.add(orderPoints.get(orderPoints.size()-1));
      orderPoints.add(0,orderPoints.get(0));
     }
     
     // create space object to draw new elements
  Space result = Space.createUnion(UNRBSname);
 // calculate Uniform Nonrational Spline Curve
  for (int i=3; i<= orderPoints.size()-2; i++) {
   for (int t=0; t<subdiv; t++) {
    curvePoints.add(unrbsCalc(orderPoints.subList(i-3, i+1),t/subdiv));
   }
  }
  // draw Spline Curve
  for (int i=1;i<curvePoints.size()-1;i++) {
   result.add(new Edge(curvePoints.get(i-1),curvePoints.get(i)));
  }
  
  
  net.getOwner().add(result);
    }
  }
}
Share

Chain model – simple simulation

Sunday, November 15th, 2009

Wrote a simple script that simulates chain models in Microstation. A series of chain segments of a specific length is defined. Some knots are fix others can move.

 

‘Simulation of a chain model
‘Sebastian Gmelin
’15.11.2009

Option Explicit

Const gravity As Double = 1 / 5
Const springforce As Double = 1 / 8
Const attrForce As Double = 3

Public Type sphere
    number As Long
    radius As Double
    center As Point3d
    newCenter As Point3d
    sElements(3) As Element
    numNeighbours As Long
    Neighbours(10) As Long
    connections(10) As Element
    moveable As Boolean
End Type

Dim spheres() As sphere

Function createSphere(pos As Point3d, rad As Double, number As Long, moveable As Boolean) As sphere
   
    Dim elem As Element
    Dim mat As Matrix3d
   
    createSphere.center = pos
    createSphere.newCenter = pos
    createSphere.radius = rad
    createSphere.moveable = moveable
    createSphere.number = number
    createSphere.numNeighbours = 0
   
    Set elem = CreateLineElement2(Nothing, pos, pos)
    elem.Color = 3
    If moveable Then elem.Color = 1
    elem.LineWeight = 8
    elem.LineStyle = ActiveDesignFile.LineStyles(1)
    ActiveModelReference.AddElement elem
    elem.Redraw
    Set createSphere.sElements(0) = elem
   
    mat = Matrix3dFromAxisAndRotationAngle(2, 0)
    Set elem = CreateEllipseElement2(Nothing, pos, rad, rad, mat, msdFillModeNotFilled)
    elem.Color = 6
    elem.LineWeight = 0
    elem.LineStyle = ActiveDesignFile.LineStyles(2)
    ActiveModelReference.AddElement elem
    elem.Redraw
    Set createSphere.sElements(1) = elem
   
    mat = Matrix3dFromAxisAndRotationAngle(1, Pi / 2)
    Set elem = CreateEllipseElement2(Nothing, pos, rad, rad, mat, msdFillModeNotFilled)
    elem.Color = 6
    elem.LineWeight = 0
    elem.LineStyle = ActiveDesignFile.LineStyles(2)
    ActiveModelReference.AddElement elem
    elem.Redraw
    Set createSphere.sElements(2) = elem
   
    mat = Matrix3dFromAxisAndRotationAngle(0, Pi / 2)
    Set elem = CreateEllipseElement2(Nothing, pos, rad, rad, mat, msdFillModeNotFilled)
    elem.Color = 6
    elem.LineWeight = 0
    elem.LineStyle = ActiveDesignFile.LineStyles(2)
    ActiveModelReference.AddElement elem
    elem.Redraw
    Set createSphere.sElements(3) = elem
   
End Function

Sub moveSphere(s As sphere, vec As Point3d)

    Dim i As Long
   
    s.center = Point3dAdd(s.center, vec)
   
    For i = 0 To UBound(s.sElements)
        Call s.sElements(i).Move(vec)
        s.sElements(i).Rewrite
        s.sElements(i).Redraw
        ‘ActiveDesignFile.Views(1).Redraw
    Next i
   
End Sub

Sub moveConnections()

    Dim s As Long
    Dim c As Long
   
    For s = 0 To UBound(spheres)
        For c = 0 To spheres(s).numNeighbours – 1
            Call spheres(s).connections(c).AsLineElement.ModifyVertex(0, spheres(s).center)
            Call spheres(s).connections(c).AsLineElement.ModifyVertex(1, spheres(spheres(s).Neighbours(c)).center)
            spheres(s).connections(c).Rewrite
            spheres(s).connections(c).Redraw
        Next c
    Next s

End Sub

Sub makeSphereFix(s As Long)

    spheres(s).moveable = False
    spheres(s).sElements(0).Color = 3
    spheres(s).sElements(0).Rewrite
    spheres(s).sElements(0).Redraw

End Sub

Sub makeSphereMoveAble(s As Long)

    spheres(s).moveable = True
    spheres(s).sElements(0).Color = 1
    spheres(s).sElements(0).Rewrite
    spheres(s).sElements(0).Redraw

End Sub

Sub drawConnections(s As Long)

    Dim elem As Element
    Dim points(1) As Point3d
    Dim i As Long
   
    For i = 0 To spheres(s).numNeighbours – 1
        points(0) = spheres(s).center
        points(1) = spheres(spheres(s).Neighbours(i)).center
        Set elem = CreateLineElement1(Nothing, points)
        elem.Color = 2
        elem.LineWeight = 2
        elem.LineStyle = ActiveDesignFile.LineStyles(1)
        ActiveModelReference.AddElement elem
        elem.Redraw
        Set spheres(s).connections(i) = elem
    Next i

End Sub

Sub calculateSphereMove(s As Long)

    Dim i As Long
    Dim k As Long
    Dim direction As Point3d
    Dim dist As Double
    Dim length As Double
    Dim grav As Boolean
    Dim vec As Point3d
    Dim tension As Double
   
    If spheres(s).moveable Then
    tension = 0
        For i = 0 To spheres(s).numNeighbours – 1
            direction = Point3dSubtract(spheres(spheres(s).Neighbours(i)).center, spheres(s).newCenter)
            dist = Abs(Point3dMagnitude(direction))
            ‘Debug.Print (“distance ” + CStr(dist))
            length = spheres(s).radius + spheres(spheres(s).Neighbours(i)).radius
            ‘Debug.Print (“length ” + CStr(length))
            tension = tension + dist – length
        Next i
        tension = tension / (spheres(s).numNeighbours)
        grav = True
        If tension > 0 Then
            spheres(s).newCenter = Point3dAdd(spheres(s).newCenter, Point3dFromXYZ(0, 0, -0.1 * gravity))
        Else
            spheres(s).newCenter = Point3dAdd(spheres(s).newCenter, Point3dFromXYZ(0, 0, -1 * gravity))
        End If
        vec = Point3dFromXYZ(0, 0, 0)
        For i = 0 To spheres(s).numNeighbours – 1
            direction = Point3dSubtract(spheres(spheres(s).Neighbours(i)).center, spheres(s).newCenter)
            dist = Abs(Point3dMagnitude(direction))
            ‘Debug.Print (“distance ” + CStr(dist))
            length = spheres(s).radius + spheres(spheres(s).Neighbours(i)).radius
            ‘Debug.Print (“length ” + CStr(length))
            If (dist – length) > 0 Then
                grav = False
                direction = Point3dScale(direction, attrForce * springforce * (dist – length) / (dist))
            Else
                direction = Point3dScale(direction, springforce * (dist – length) / (dist))
            End If
            vec = Point3dAdd(vec, direction)
        Next i
        spheres(s).newCenter = Point3dAdd(spheres(s).newCenter, vec)
    End If

End Sub

Sub moveSpheres()

    Dim i As Long
    Dim s As Long
    Dim vec As Point3d
   
    For s = 0 To UBound(spheres)
        vec = Point3dSubtract(spheres(s).newCenter, spheres(s).center)
        spheres(s).center = spheres(s).newCenter
   
        For i = 0 To UBound(spheres(s).sElements)
            Call spheres(s).sElements(i).Move(vec)
            spheres(s).sElements(i).Rewrite
            spheres(s).sElements(i).Redraw
            ‘ActiveDesignFile.Views(1).Redraw
        Next i
    Next s

End Sub

 

Sub Main()

    Dim i As Long
    Dim k As Long
    Dim s As Long
   
    Randomize

    ReDim spheres(99)
    For i = 0 To 9
        For k = 0 To 9
            spheres(i * 10 + k) = createSphere(Point3dFromXYZ(i, k, 0), 0.65, i * 10 + k, True)
        Next k
    Next i
   
    For i = 0 To 9
        For k = 0 To 9
            ‘spheres(i * 10 + k) = createSphere(Point3dFromXYZ(i, k, 0), rnd * 0.2 + 0.5, i * 10 + k, True)
            If i < 9 Then
                spheres(i * 10 + k).Neighbours(spheres(i * 10 + k).numNeighbours) = i * 10 + k + 10
                spheres(i * 10 + k).numNeighbours = spheres(i * 10 + k).numNeighbours + 1
            End If
            If k < 9 Then
                spheres(i * 10 + k).Neighbours(spheres(i * 10 + k).numNeighbours) = i * 10 + k + 1
                spheres(i * 10 + k).numNeighbours = spheres(i * 10 + k).numNeighbours + 1
            End If
            If i > 0 Then
                spheres(i * 10 + k).Neighbours(spheres(i * 10 + k).numNeighbours) = i * 10 + k – 10
                spheres(i * 10 + k).numNeighbours = spheres(i * 10 + k).numNeighbours + 1
            End If
            If k > 0 Then
                spheres(i * 10 + k).Neighbours(spheres(i * 10 + k).numNeighbours) = i * 10 + k – 1
                spheres(i * 10 + k).numNeighbours = spheres(i * 10 + k).numNeighbours + 1
            End If
            Call drawConnections(i * 10 + k)
        Next k
    Next i
   
    ‘Call makeSphereFix(0)
    Call makeSphereFix(9)
    ‘Call makeSphereFix(55)
    Call makeSphereFix(90)
    Call makeSphereFix(99)
   
    For i = 0 To 75
‘        Call moveSphere(spheres(Round(Rnd * 99)), Point3dFromXYZ(0, 0, Rnd * 0.5 – 0.25))
‘        Call moveConnections
        For s = 0 To UBound(spheres)
            Call calculateSphereMove(s)
        Next s
        Call moveSpheres
        Call moveConnections
        ActiveDesignFile.Views(1).Redraw
    Next i
   
End Sub

Share

Hyperbolic Paraboloids – math model

Wednesday, November 11th, 2009

Hyperbolic paraboloids (HP) are discribed by the formula
\frac{x^2}{a^2} - \frac{y^2}{b^2} - 2z = 0
The below script creates HPs in Microstation within a certain range of  x and y coordinates. The dashed lines indicate the regular grid on coordinate system. These are of parabolic shape. The thick diagonal lines are all straight. They are the reason why this shape is interesting for construction, as it can be discribed as a series of straight lines. Intersecting the surface with a horizontal plane creates hyperbolas (blue curves).

Hyperbolic paraboloid

Hyperbolic paraboloid

‘Hyperbolic Paraboloids
‘Sebastian Gmelin
’11.11.2009

Const a As Double = 2
Const b As Double = 2

Const range As Long = 8

Dim hp() As Point3d

Dim x As Double
Dim y As Double
Dim z As Double
   
Dim point As Point3d

Dim ele As element
Sub drawGrid()

Dim points() As Point3d

ReDim points(range * 2)

    For x = range * -1 To range
        For y = range * -1 To range
            points(y + range) = hp(x + range, y + range)
        Next y
        Set ele = CreateLineElement1(Nothing, points)
        ele.Color = 4
        ele.LineWeight = 0
        ActiveModelReference.AddElement ele
        ele.Redraw
    Next x
   
    For y = range * -1 To range
        For x = range * -1 To range
            points(x + range) = hp(x + range, y + range)
        Next x
        Set ele = CreateLineElement1(Nothing, points)
        ele.Color = 4
        ele.LineWeight = 0
        ActiveModelReference.AddElement ele
        ele.Redraw
    Next y

End Sub
Sub drawDiaGrid()

Dim points() As Point3d
Dim i As Long

    For i = 1 To range * 2
        x = range * -1
        ReDim points(i)
        For y = range – i To range
            points(y – range + i) = hp(x + y + i, y + range)
        Next y
        Set ele = CreateLineElement1(Nothing, points)
        ele.Color = 7
        ele.LineWeight = 1
        ActiveModelReference.AddElement ele
        ele.Redraw
       
        For y = i To 0 Step -1
            points(i – y) = hp(i – y, y)
        Next y
        Set ele = CreateLineElement1(Nothing, points)
        ele.Color = 7
        ele.LineWeight = 1
        ActiveModelReference.AddElement ele
        ele.Redraw
       
        If i < range * 2 Then
            y = range * -1
            ReDim points(range * 2 – i)
            For x = range * -1 + i To range
                points(x + range – i) = hp(x + range, y + range * 2 + x – i)
            Next x
            Set ele = CreateLineElement1(Nothing, points)
            ele.Color = 7
            ele.LineWeight = 1
            ActiveModelReference.AddElement ele
            ele.Redraw
           
            y = range
            ReDim points(range * 2 – i)
            For x = range * -1 + i To range
                points(x + range – i) = hp(x + range, y – x + i)
            Next x
            Set ele = CreateLineElement1(Nothing, points)
            ele.Color = 7
            ele.LineWeight = 1
            ActiveModelReference.AddElement ele
            ele.Redraw
        End If
    Next i
   
   
End Sub

Sub horizontalCut(cz As Double)

Dim points() As Point3d
Dim pointsNeg() As Point3d

ReDim points(range * 2)
ReDim pointsNeg(range * 2)
   
    If cz >= 0 Then
        For y = range * -1 To range
            x = Math.Sqr(a * a * (((y * y) / (b * b)) + 2 * cz))
            points(y + range) = Point3dFromXYZ(x, y, cz)
            pointsNeg(y + range) = Point3dFromXYZ(-1 * x, y, cz)
        Next y
    Else
        For x = range * -1 To range
            y = Math.Sqr(b * b * (((x * x) / (a * a)) – 2 * cz))
            points(x + range) = Point3dFromXYZ(x, y, cz)
            pointsNeg(x + range) = Point3dFromXYZ(x, -1 * y, cz)
        Next x
    End If

    Set ele = CreateLineElement1(Nothing, points)
    ele.Color = 5
    ele.LineWeight = 2
    ActiveModelReference.AddElement ele
    ele.Redraw
   
    Set ele = CreateLineElement1(Nothing, pointsNeg)
    ele.Color = 5
    ele.LineWeight = 2
    ActiveModelReference.AddElement ele
    ele.Redraw

End Sub

 

Sub Main()
   
    ReDim hp(range * 2, range * 2)
   
    For x = range * -1 To range
        For y = range * -1 To range
            z = (((x * x) / (a * a)) – ((y * y) / (b * b))) / 2
            point = Point3dFromXYZ(x, y, z)
            Set ele = CreateLineElement2(Nothing, point, point)
            ele.Color = 3
            ele.LineWeight = 10
            ActiveModelReference.AddElement ele
            ele.Redraw
            hp(x + range, y + range) = point
        Next y
    Next x
   
    drawGrid
    drawDiaGrid
    horizontalCut (range / 2)
    horizontalCut (range / -2)

End Sub

Share

Bezier Curves, algorithm of de Casteljau

Sunday, November 1st, 2009

I started reading on Curve models and geometries, different types of Spline algorithms. This is a first attempt to generate Bezier curvers using the algorithm of de Casteljau. The script uses a selected polyline as the control polygon of the curve. The Bezier is created in several steps to illustrate the process. It runs under Microstation MVBA.

Bezier curve of degree 3

Bezier curve of degree 3

Bezier curve of degree 4

Bezier curve of degree 4

Bezier curve of degree 5

Bezier curve of degree 5

Bezier curve of degree 8

Bezier curve of degree 8

‘Linestring Bezier Approximation after Casteljau’s algorithm
‘Sebastian Gmelin
’24.10.2009

‘draw and select linestring and run script

Const cDiv As Long = 5 ‘subdivision at which guidlines are drawn and a copy of the drawing set is created
Const div As Long = 50 ‘subdivision between cDiv for bezier spline points (total subdivision = cDiv * div)

Dim cPoints() As Point3d
Dim bPoints() As Point3d
Dim cSize As Point3d
Dim cLine As Element
Private Sub ScanDesignFile()
‘scan active designfile for selected linestrings
    Dim oElEnum As ElementEnumerator
    Dim oElem As Element

    ‘get collection of selected elements
    Set oElEnum = ActiveModelReference.GetSelectedElements
    ActiveModelReference.UnselectAllElements
   
    ‘go through selection set
    While oElEnum.MoveNext
        Set oElem = oElEnum.Current
        ‘check if active element is linestring
        If (oElem.IsVertexList) Then
            Debug.Print (“Linestring”)
            cPoints = oElem.AsVertexList.GetVertices ‘save collection of vertices
            Set cLine = oElem
        End If
    Wend
End Sub

Private Sub getSize()
‘get linestring size for element copies offset

Dim i As Long
Dim min As Point3d
Dim max As Point3d
Dim lineString As Element

    min = Point3dFromXYZ(1E+17, 1E+17, 1E+17)
    max = Point3dFromXYZ(-1E+17, -1E+17, -1E+17)
   
    For i = 0 To UBound(cPoints)
        If cPoints(i).X > max.X Then max.X = cPoints(i).X
        If cPoints(i).Y > max.Y Then max.Y = cPoints(i).Y
        If cPoints(i).Z > max.Z Then max.Z = cPoints(i).Z
        If cPoints(i).X < min.X Then min.X = cPoints(i).X
        If cPoints(i).Y < min.Y Then min.Y = cPoints(i).Y
        If cPoints(i).Z < min.Z Then min.Z = cPoints(i).Z
    Next
   
    cSize = Point3dFromXYZ(0, max.Y – min.Y, 0)
    cSize.Y = cSize.Y * -1.2
   
End Sub

Sub Casteljau()

Dim i As Long
Dim k As Double
Dim p As Long
Dim points() As Point3d ‘last parent point collection
Dim dPoints() As Point3d ‘division points
Dim mPoints() As Point3d ‘points to draw
Dim lineString As Element
Dim color As Long
Dim count As Long
Dim moveCount As Long

ReDim bPoints(0)
bPoints(0) = cPoints(0)
count = 0
moveCount = 0

For k = 1 / (div * cDiv) To 1 Step 1 / (div * cDiv) ‘k is scale factor of divisions
    points = cPoints
    dPoints = cPoints
    color = 48
    ‘calculate divisions
    While UBound(dPoints) > 1
    ‘points is the collection of vertices of the parent linestring
    ‘dPoints is the child linestring at scalefactor k
        For i = 0 To UBound(points) – 1
            dPoints(i) = Point3dAdd(Point3dScale(Point3dSubtract(points(i + 1), points(i)), k), points(i))
        Next i
        ReDim Preserve dPoints(UBound(points) – 1)
        ‘draw guidlines
        If count = div Then
            mPoints = dPoints
            ‘calculate offset
            For p = 0 To UBound(mPoints)
                mPoints(p) = Point3dAdd(mPoints(p), Point3dScale(cSize, moveCount))
            Next
            ‘draw line
            Set lineString = CreateLineElement1(Nothing, mPoints)
            lineString.color = color
            lineString.LineStyle = ActiveDesignFile.LineStyles(3)
            ActiveModelReference.AddElement lineString
            lineString.Redraw
            color = color + 48
        End If
        points = dPoints
    Wend
    count = count + 1
    ‘draw progress of bezier curve
    If count > div Then
        count = 0
        ‘copy control polygon
        Set lineString = ActiveModelReference.CopyElement(cLine)
        Call lineString.Move(Point3dScale(cSize, moveCount))
        ActiveModelReference.AddElement lineString
        lineString.Redraw
        moveCount = moveCount + 1
        ‘calculate offset of beziers pline
        mPoints = bPoints
        For p = 0 To UBound(mPoints)
            mPoints(p) = Point3dAdd(mPoints(p), Point3dScale(cSize, moveCount – 1))
        Next
        ‘draw bezier progress
        Set lineString = CreateLineElement1(Nothing, mPoints)
        lineString.color = 3
        lineString.LineWeight = 2
        ActiveModelReference.AddElement lineString
        lineString.Redraw
    End If
    ‘add calculated division point to collection of bezier points
    ReDim Preserve bPoints(UBound(bPoints) + 1)
    bPoints(UBound(bPoints)) = Point3dAdd(Point3dScale(Point3dSubtract(points(1), points(0)), k), points(0))
Next k

‘draw final bezier curve
mPoints = bPoints
For p = 0 To UBound(mPoints)
    mPoints(p) = Point3dAdd(mPoints(p), Point3dScale(cSize, moveCount – 1))
Next
Set lineString = CreateLineElement1(Nothing, mPoints)
lineString.color = 3
lineString.LineWeight = 2
ActiveModelReference.AddElement lineString
lineString.Redraw

End Sub
Sub Main()

    If ActiveModelReference.AnyElementsSelected Then
        ScanDesignFile
        getSize
        Casteljau
    End If

End Sub

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

more Bezier curves

Share

Johannes Itten – “Tower of Fire”,parametric model

Wednesday, October 21st, 2009

Having seen a rebuilt of Itten’s “Tower of Fire” at the Bauhaus exhibition, I started swcripting a parametric model of the tower in the spirit of the workshop we’re planning to do next year. The VBA script runs in Microstation and is modified by the following parameters:

  • cSize As Double = edgeLength of the bottom cube
  • cAngle As Double = rotation in plan between each cube
  • cNumber As Long = number of cubes / levels
  • cScale As Double = the bottom radii of the cones equals the diagnal conrner distance by default. This is scaled by cScale parameter
  • uSeg As Long = Number of linear panels on cone
  • vSeg As Long = Number of circular panels on cone
  • cRad As Double = Radius of panel frames

Images of rebuilts of the tower:

Examples of towers using different parameters:
tower of fire 01

tower of fire 01

tower of fire 01 top view

tower of fire 01 top view

tower of fire 02

tower of fire 02

tower of fire 02 top view

tower of fire 02 top view

tower of fire 03

tower of fire 03

tower of fire 03 top view

tower of fire 03 top view

Source code for Microstation MVBA:

‘Draw a “tower of fire”
‘Parametric approach to Johannes Itten’s design
‘Sebastian Gmelin
’19.10.2009

Option Explicit

Const cSize As Double = 60
Const cAngle As Double = 3
Const cNumber As Long = 40
Const cScale As Double = 2
Const uSeg As Long = 10
Const vSeg As Long = 1
Const cRad As Double = 0.05

Public Type cube
    height As Double
    startPoint As Point3d
    endPoint As Point3d
    direction As Point3d
    botVertex(5) As Point3d
    topVertex(5) As Point3d
End Type

Dim cubes() As cube
Sub Main()
    Dim i As Long
    Dim k As Long
    Dim p As Long
    Dim q As Long
    Dim size As Double
    Dim direction As Point3d
    Dim startPoint As Point3d
    Dim endPoint As Point3d
    Dim height As Double
    Dim cOffset As Double
    Dim conePoints(4) As Point3d
    Dim cSpans() As Point2d
   
    Dim cSurface As New BsplineSurface
    Dim cCurves(2) As New BsplineCurve
    Dim isoCurves() As New BsplineCurve
    Dim cPath As New BsplineCurve
       
    Dim line As Element
    Dim coneEdge(2) As Element
    Dim cLine(3) As Element
    Dim cArc As Element
    Dim cSurfElement As BsplineSurfaceElement
    Dim cSpline As BsplineCurveElement
   
    ReDim cubes(cNumber)
    
    size = cSize
    direction = Point3dFromXYZ(1, 0, 0)
    startPoint = Point3dFromXYZ(size / -2, size / 2, 0)
    endPoint = Point3dFromXYZ(size / 2, size / 2, 0)
    height = Point3dDistance(endPoint, startPoint)
   
    For i = 1 To cNumber
        Call createBox(startPoint, endPoint)
       
        cOffset = Atn(cAngle * 3.141 / 180) * height
        height = Point3dDistance(endPoint, startPoint)
       
        ‘store data
        cubes(i).height = height
        cubes(i).startPoint = startPoint
        cubes(i).endPoint = endPoint
        cubes(i).direction = direction
        cubes(i).botVertex(1) = startPoint
        cubes(i).botVertex(2) = endPoint
        cubes(i).botVertex(3) = Point3dSubtract(endPoint, Point3dCrossProduct(Point3dSubtract(endPoint, startPoint), Point3dFromXYZ(0, 0, 1)))
        cubes(i).botVertex(4) = Point3dSubtract(startPoint, Point3dCrossProduct(Point3dSubtract(endPoint, startPoint), Point3dFromXYZ(0, 0, 1)))
        cubes(i).botVertex(0) = cubes(i).botVertex(4)
        cubes(i).botVertex(5) = cubes(i).botVertex(1)
        For k = 0 To 5
            cubes(i).topVertex(k) = cubes(i).botVertex(k)
            cubes(i).topVertex(k).z = cubes(i).botVertex(k).z + height
        Next
       
        ‘draw testpoints
        CadInputQueue.SendCommand “ACTIVE STYLE 1″
       
        Set line = CreateLineElement2(Nothing, cubes(i).botVertex(1), cubes(i).topVertex(3))
        ActiveModelReference.AddElement line
        line.Redraw
       
        Set line = CreateLineElement2(Nothing, cubes(i).botVertex(2), cubes(i).topVertex(4))
        ActiveModelReference.AddElement line
        line.Redraw
       
        Set line = CreateLineElement2(Nothing, cubes(i).botVertex(3), cubes(i).topVertex(1))
        ActiveModelReference.AddElement line
        line.Redraw
       
        Set line = CreateLineElement2(Nothing, cubes(i).botVertex(4), cubes(i).topVertex(2))
        ActiveModelReference.AddElement line
        line.Redraw
       
        ‘change data for next cube
        startPoint = Point3dSubtract(startPoint, Point3dScale(Point3dNormalize(Point3dCrossProduct(direction, Point3dFromXYZ(0, 0, 1))), cOffset))
        endPoint = Point3dSubtract(endPoint, Point3dScale(Point3dNormalize(direction), cOffset))
        direction = Point3dSubtract(endPoint, startPoint)
        startPoint.z = startPoint.z + height
        endPoint.z = endPoint.z + height
    Next
       
    For i = 2 To cNumber
        For k = 1 To 4
            SetCExpressionValue “tcb->symbology.color”, 0, “MGDSHOOK”
            CadInputQueue.SendCommand “ACTIVE STYLE 2″
            conePoints(0) = cubes(i).topVertex(k)
            conePoints(1) = cubes(i – 1).topVertex(k)
            conePoints(2) = cubes(i).topVertex(k + 1)
            conePoints(3) = Point3dScale(Point3dAdd(conePoints(1), conePoints(2)), 0.5)
            conePoints(4) = Point3dAdd(conePoints(3), Point3dScale(Point3dNormalize(Point3dCrossProduct(Point3dSubtract(conePoints(3), conePoints(0)), Point3dSubtract(conePoints(2), conePoints(1)))), cubes(i).height * cScale))
            
            Set coneEdge(1) = CreateLineElement2(Nothing, cubes(i – 1).topVertex(k), cubes(i).topVertex(k))
            ActiveModelReference.AddElement coneEdge(1)
            coneEdge(1).Redraw
            Set coneEdge(2) = CreateLineElement2(Nothing, cubes(i).topVertex(k), cubes(i).topVertex(k + 1))
            ActiveModelReference.AddElement coneEdge(2)
            coneEdge(2).Redraw
           
            Set cLine(1) = CreateLineElement2(Nothing, conePoints(1), conePoints(2))
            ActiveModelReference.AddElement cLine(1)
            cLine(1).Redraw
            Set cLine(1) = CreateLineElement2(Nothing, conePoints(0), conePoints(3))
            ActiveModelReference.AddElement cLine(1)
            cLine(1).Redraw
            Set cLine(1) = CreateLineElement2(Nothing, conePoints(3), conePoints(4))
            ActiveModelReference.AddElement cLine(1)
            cLine(1).Redraw
           
            Set cArc = CreateArcElement3(Nothing, conePoints(1), conePoints(4), conePoints(2))
            ActiveModelReference.AddElement cArc
            cArc.Redraw
           
            Call cCurves(0).FromElement(coneEdge(1))
            Call cCurves(1).FromElement(coneEdge(2))
            Call cCurves(2).FromElement(cArc)
           
            SetCExpressionValue “tcb->symbology.color”, k, “MGDSHOOK”
            CadInputQueue.SendCommand “ACTIVE STYLE 0″
            Call cSurface.FromRailsAndSweptSections(cCurves(0), cCurves(1), cCurves(2), Nothing)
            Set cSurfElement = CreateBsplineSurfaceElement1(Nothing, cSurface)
            ActiveModelReference.AddElement cSurfElement
            cSurfElement.Redraw
           
            ‘create Network U
            For q = 0 To uSeg
                isoCurves = cSurface.ExtractIsoparametricCurve(cSpans, q / uSeg, msdBsplineSurfaceU)
                For p = LBound(isoCurves) To UBound(isoCurves)
                    Set cSpline = CreateBsplineCurveElement1(Nothing, isoCurves(p))
                    ActiveModelReference.AddElement cSpline
                    cSpline.Redraw
                    Call createTube(cRad, isoCurves(p))
                Next p
            Next q
           
            ‘create Network V
            For q = 0 To vSeg
                isoCurves = cSurface.ExtractIsoparametricCurve(cSpans, q / vSeg, msdBsplineSurfaceV)
                For p = LBound(isoCurves) To UBound(isoCurves)
                    Set cSpline = CreateBsplineCurveElement1(Nothing, isoCurves(p))
                    ActiveModelReference.AddElement cSpline
                    cSpline.Redraw
                    Call createTube(cRad, isoCurves(p))
                Next p
            Next q
        Next k
    Next i

End Sub
Sub createBox(startPoint As Point3d, endPoint As Point3d)

    CadInputQueue.SendCommand “ACTIVE STYLE 0″
    SetCExpressionValue “tcb->symbology.color”, 0, “MGDSHOOK”
   
‘   Start a command
    CadInputQueue.SendCommand “MODELER BLOCK”

‘   Set a variable associated with a dialog box
    SetCExpressionValue “tcb->ms3DToolSettings.block.axisMode”, 0, “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.length.value”, (ActiveModelReference.UORsPerMasterUnit * Abs(Point3dDistance(startPoint, endPoint))), “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.width.value”, (ActiveModelReference.UORsPerMasterUnit * Abs(Point3dDistance(startPoint, endPoint))), “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.height.value”, (ActiveModelReference.UORsPerMasterUnit * Abs(Point3dDistance(startPoint, endPoint))), “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.height.locked”, 0, “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.width.locked”, 0, “FEATURESOLID”
    SetCExpressionValue “tcb->ms3DToolSettings.block.length.locked”, 0, “FEATURESOLID”

    CadInputQueue.SendDataPoint startPoint, 1

‘   Send a keyin that can be a command string
    CadInputQueue.SendKeyin “AccuDraw Rotate Top”

    CadInputQueue.SendDataPoint endPoint, 1

    CadInputQueue.SendDataPoint Point3dSubtract(startPoint, Point3dCrossProduct(Point3dSubtract(endPoint, startPoint), Point3dFromXYZ(0, 0, 1))), 1
   
    CadInputQueue.SendDataPoint Point3dAdd(startPoint, Point3dFromXYZ(0, 0, Abs(Point3dDistance(startPoint, endPoint)))), 1

    CadInputQueue.SendCommand “CHOOSE ELEMENT”

    CommandState.StartDefaultCommand
End Sub

Sub createTube(rad As Double, path As BsplineCurve)
    Dim Frame As Matrix3d
    Dim Curvature As Double
    Dim Torsion As Double
    Dim Parameter As Double
    Dim LinearNormal As Point3d
    Dim Normal As Point3d
    Dim cPoint As Point3d
    Dim circ As Element
    Dim Rot As Matrix3d
    Dim line As Element
    Dim x As Point3d
    Dim y As Point3d
    Dim z As Point3d
    Dim startPoint As Point3d
    Dim endPoint As Point3d
   
    Dim cSurface As New BsplineSurface
    Dim cSurfElement As BsplineSurfaceElement
    Dim cSection As New BsplineCurve
       
    endPoint = path.EvaluatePointFrame(Frame, Curvature, Torsion, 1, LinearNormal)
    startPoint = path.EvaluatePointFrame(Frame, Curvature, Torsion, 0, LinearNormal)
    cPoint = startPoint
   
    y = Point3dNormalize(Point3dCrossProduct(Frame.RowY, Frame.RowX))
    z = Point3dNormalize(Frame.RowX)
    x = Point3dNormalize(Point3dCrossProduct(y, z))
   
    Rot = Matrix3dFromPoint3dColumns(x, y, z)
   
    Set line = CreateLineElement2(Nothing, cPoint, Point3dAdd(cPoint, x))
    line.Color = 1
    ActiveModelReference.AddElement line
    line.Redraw
   
    Set line = CreateLineElement2(Nothing, cPoint, Point3dAdd(cPoint, y))
    line.Color = 2
    ActiveModelReference.AddElement line
    line.Redraw
   
    Set line = CreateLineElement2(Nothing, cPoint, Point3dAdd(cPoint, z))
    line.Color = 3
    ActiveModelReference.AddElement line
    line.Redraw
   
    Set circ = CreateEllipseElement2(Nothing, cPoint, rad, rad, Rot)
    ActiveModelReference.AddElement circ
    circ.Redraw
   
    Call cSection.FromElement(circ)
    SetCExpressionValue “tcb->symbology.color”, 6, “MGDSHOOK”
    CadInputQueue.SendCommand “ACTIVE STYLE 0″
    Call cSurface.FromRailAndSweptSection(path, cSection)
    Set cSurfElement = CreateBsplineSurfaceElement1(Nothing, cSurface)
    ActiveModelReference.AddElement cSurfElement
    cSurfElement.Redraw
       
End Sub

Share