Saturday, February 20, 2010

Surfaces of revolution and parametric surfaces.


Some time ago, before I started writing this blog. I implemented a structure/mechanism in FreeREP for dealing with non planar surfaces. In particular there needs to be a way to triangulate such things for display and to define various trimmings on the surfaces. With non planar surfaces, various things we take for granted, just don't make sense. For example, say you want to see if a curve is clockwise/anticlockwise, and this curve lies on the surface of the sphere. There really is no way to define cw/ccw on the surface of a sphere. Supposing you did make some arbitrary definition, calculating which one it is will become abhorrently complex.

To deal with these problems in general, geometry kernel's usually implement parametric surfaces. This is where you use a D dimensional field to do operations on a D dimensional object embedded in a >D dimensional space. The simplest example is actually a planar surface. Calculating, for example, the area of a planar face should be easy. No matter what plane they are on. But calculating the double integral for 3d arcs and lines is not easy. So instead we project the 3d lines and arcs onto a 2d plane. Now we have much easier integrals to deal with. As it turns out we can do something similar with any surface. The key is to find a good mapping. One that makes calculations easy, and most importantly preserves certain geometrical properties. In particular 2 non intersecting curves in D dimensional space. Cannot intersect in parametric space.

With FreeREP, i thought I had the master plan. With spheres and cones, it is possible to limit the maximum surface size to a portion of the sphere or cone. This means representing a whole cone with 4 surfaces, and a whole sphere with 8. Then each of these surfaces defines a plane that has a normal which the average normal over the projected surface. As it happens, the maximum deviation of the real normal to the plane normal is never more than PI/4. Then stuff is really easy. To project a curve onto its surface all we do is set the Z coordinate to 0.

Welcome IGES. I knew it wouldn't last. The above scheme gets really screwy with nurbs. You would have to split the surface along totally random curves that would be both hard to find, and hard to define. But so soon? I never imagined. The trouble came with implementing IGES surfaces of revolution. These are effectively defined in parametric space. A space very unlike FreeREP's. I considered some quick and dirty options for the conversion of spaces, but they all were hacks and wouldn't work for the general case. The only robust solution would be to implement there notion of parametric space, project the curves into it, and use 2d boolean operations to see how there parametric space overlapped the FreeREP faces bounds. But 2d boolean ops are actually very difficult to get working right, and FreeREP doesn't yet have the tools to deal with numerical issues, so that seemed aways off. Instead I decided to implement proper parametric spaces in FreeREP.

The triangulator has undergone major modifications. Nothing serious but things have different names and pass slightly different parameters. So alot of stuff is broken, ie everything. I have succefully created a hemisphere on a single surface in parametric space S(tX).

There are still a couple of bugs, but things should come back together pretty easily now.

Sunday, February 14, 2010

IGES import

A geometry kernel has got to have some way to import geometry. This gives the kernel a burst of much needed entropy when developing tests for different algorithms. Since the first working geometry algorithm in FreeREP will be the meshing utilities. It seemed only logical to start importing some models. I considered both STEP and IGES for the first model format. While STEP is much more modern and well thought out. It is sickeningly complicated. They have gone ahead and defined there own version of Backus-Naur form, called Express. Which they use to define the grammar for both Express, and the application protocols. Writing a parser generator for these would need to be done to get a standards compliant parser, and is probably the easiest way to do it. But I'm a little more interested in geometry, so lets flash back to the 1970's when programmers did some even more rediculous crap, but at least it doesn't require 50,000 lines of code to parse your first model.

You know its bad when the only people with a copy of specification refer to themselves as a preservation society. But it's even worse when the preservation society doesn't seem to have a copy of the previous 20 versions of the specification. Get all your IGES info at the archive http://www.iges5x.org/ There are some illusions to the state of the previous specifications in the current one. Fortunately that can all be ignored for now because the models I am using for testing are generated in Catia, which outputs IGES 5.3. So parsing this stuff is pretty easy if strange. It's 80 column formatted, for use with punch cards (don't fold spindle or mutilate), uses Holerith code strings, and has to use this weird line pointer system because double precision numbers don't tend to fit in fixed width fields very well. I guess you never have to worry about running out of memory as this all breaks when there are more than 49,999 entities.

So the first order of business was loading all the wires. Just a bunch of lines and arcs and all went pretty smoothly. Except with the peculiarity that Catia seems to export planar arcs using a transfomation matrix. They are always located at 0,0,0 with a start angle of 0. Then you have to tranaform them to where they go in world space. That needed to get implemented anyways, so no big deal. Then I moved on to turning the edges into faces. Needed some flashy math here, as IGES defines a plane as Ax+By+Cd=D, and FreeREP uses something like a Geom_Ax2, if you are familiar with opencascade. If not, it is a location, a norm, and a perpendicular vector to the norm which defines the x axis. This gives a better basis for rotations and such. As the cartesian plane doesn't really define a mapping, just what set is on the plane. That leaves us at the screen shot. You can see it is not rendering the cylindrical face yet, we will need surfaces of revolution for that. What it is doing, is loading the IGES file, meshing it, and drawing it to the screen, in a little less than 5ms.

Introduction

Hi All. I am jonpry, the creator and maintainer of the FreeREP opensource free-software BREP library. There has been quite a lot going on with this code, and some things are starting to shape up. Since FreeREP is just a library and has no user interface, it is difficult for people to see what it does, how to use it, and what it is capable of. Therfore I decided to start blogging about the development of this kernel. Unfortunately, really useable improvements are far between. So for the most part this blog will have lots of mathematics and griping about stupid software and standards. The source repo is located here http://code.google.com/p/freerep/