Saturday, December 5, 2009

Refactorings... and again Refactorings

Yesterday I've started a refactor to try to resolve a class of problems. Firstly, how is organized Naro code, and what is the relation with OpenCascade?

NaroCAD is built as MVC, in multiple levels, but in short, the primitives are stored persistently in a structure named Document. This document have a tree which is somehow similar with XML DOM (but indexed a bit differenly to have better access time), and livecycle (like Undo, Redo). The tree nodes can store arbitrary data, or as needed it can store shapes that based on that data, to builds visual OpenCascade shapes. Those high level shapes are stored in two ways: as model with specific OpenCascade code named Functions and as OpenCascade View, if a document have an attached OpenCascade Context the view show/hide, color, etc. is done automatically (using a custom attribute) based on propagation, changing in attributes that are on the node. So making those lines short, A document attached to OpenCascade, it will wrap it with high level primitives and tools (like Extrude, Circle, etc.)

To make them appear in the final document, users expect a preview, so for this there is a separate component that do only visual work (that at the end will create to you a shape like circle you wanted). This component describe actions that users do click that are named Modifiers. A modifier starts from the moment you click the button in toolbar and continues until user press escape or click on other toolbar button.

For some shapes it simply work as to create the shape in-place and to simply update the dependent data lively. For older code or for cases when the code was not thought as that way, the OpenCascade code was done by hand. So by this, some actions did use a AIS_Interactive visual shape that was updated as Circle first, Cylinder after and added/removed manually to OpenCascade's cotnext.

The refactor did start from observation that is much easier to use NaroCAD's framework to add a circle in Document (and document will do by itself the circle live-cycle) than to write it's OpenCascade code. Also we remove the copy/paste code of creating circle. In case that circle code will have a small issue, the fix should be done wherever the code was the same in preview. Want to clean your scene from when your action starts? Document.Revert(); is just enough in all cases. No if(TemporaryShape!=null){ Context.Remove(TemporaryShape, true); }

How many shapes are affected by this refactor? The code affects around 30 modifiers in code, but this new model in all cases reduce the code line count, make all code to not be OCC like but more C#/NaroCAD framework like. The other advantage is that if your final shape is not right defined, it can be reveted the code without having the possibility that by mistake some temporary shapes are remaining in OCC context.

No comments: