Again if you want to contact me directly just hit me up here or leave a comment.
Monday, August 31, 2009
Converting SketchUp models to QUEST pdb files
Again if you want to contact me directly just hit me up here or leave a comment.
Tuesday, August 25, 2009
How to run QUEST from Excel VBA and wait for QUEST to finish
Split function in SCL
VBA has a function called Split that is handy for parsing strings to an array based on some delimiter. All you have to do is dim out an array variable and say:
ArrayVar = Split( "the,split,string" , "," ) and your ArrayVar will contain three strings, "the" , "split", and "string".
There is no in-built function in SCL to do this, so I have put together something that should work in a similar fashion. I have named the function the same, though the difference here is because SCL's arrays are fixed in size, where with VBA you can dynamically size arrays.
To get around this, you must first declare a String array in the Var section of your calling procedure (or globally), and pass that into the Split function as the last argument. You must also provide the upper bound of the array to the function. This upper bound is not the highest index of the array (which is one minus the size of the array), but just the size of the array. One easy way to use this information is to declare your arrays using Const's denoting the size of the array. For example:
procedure some_proc()
Const
arr_size 10
Var
my_array : Array[ arr_size ] of String
........
So, in this case, if you wanted to split a string into my_array, you would do this:
num_elems = split( 'some delimited line' , ' ' , arr_size , my_array )
where num_elems is the number of chunks of text split into the array. If there are more chunks than there are bins in your array, any trailing chunks will be ignored, and no error will be raised.
I have tested this routine a bit, so it should work fairly well, even with multi-character delimiters. On a side note, you should put this routine into your always available routines in QUEST.
routine split( the_line : String ; the_delim : String ; max_elements : Integer ; Var the_array : Array[] of String ) : Integer
Var
write_idx , delim_idx : Integer
check_char : String
Begin
while( len( the_line ) > 0 ) do
if( write_idx < max_elements ) then
delim_idx = index( the_line , the_delim , 1 )
--write( 'delim_idx=' , delim_idx , cr )
if( delim_idx > 0 ) then
the_array[ write_idx ] = leftstr( the_line , delim_idx - 1 )
the_line = rightstr( the_line , len( the_line ) - delim_idx - len( the_delim ) + 1 )
else
-- no more delimeters left - write the last of the_line to the array
the_array[ write_idx ] = the_line
the_line = '' -- empty the_line so we break from the while loop
endif
write_idx = write_idx + 1
else
the_line = '' -- empty the_line so we break from the while loop
endif
endwhile
return write_idx -- return number of pieces written to array
End
Tuesday, August 18, 2009
Evaluating string expressions in SCL
Tuesday, August 4, 2009
Quest_Geom
I've used the same solution Martin described, and clumsy is an understatement, but it has worked fairly well for me in the past. From what I've seen of the format, it's similar to the wavefront obj format, if that helps...
Here's an overview of how a basic QUEST geometry file is laid out, just from my messing around with these files...I have no expertise in how the format works, this is all based on observation and guesses.
All these observations are based on a basic rectangular block I created in QUEST D5R18.
Basically the file starts with the number 12, probably a version number or something, then some vector transformation information, probably for locating and rotating the geometry, though I've never messed around with that. After all this information there is an asterisk indicating the geometry section is beginning. I've found that older geometry files don't have this asterisk to delineate between geometry sections.
For a basic rectangular box, there are 8 points, for each of the 8 corners on the box.
After the first asterisk, there is a number indicating the number of points in the geometry. Points serve as vertices for lines. After listing the number of vertices, you list out the xyz location of each vertex.
After the vertices you list out something, and I either never knew or forgot what it is, but the geometry I'm looking at now has a zero.
Next we indicate the number of and list out all the lines in the geometry. So if we have a rectangular box we have a total of 12 lines, as you can see in the diagram below.
To describe a line, we have to provide the index of each of the two vertices in the line. QUEST basically reads the initial list of points in as a zero-indexed array, which means the first entry is point number zero in the array.
In this case, line 1 is composed of points 1 and 2, so our first line is represented as "1 2"
Next we indicate the number of and list out all the polygon faces in the geometry. So if we have a rectangular box we have a total of 6 faces, as you can see in the diagram below.
The definition of a polygon is simply a list of the line indices composing that face preceded by the number of lines composing the face. The direction of the line makes a difference, here. The lines of a polygon must all go in the same direction - either clockwise around the face or counter-clockwise. So, if a line is defined backwards from the direction of the other lines in the polygon, you must place a minus sign before that line number, and QUEST will interpret that and represent the polygon properly.
The last section we'll discuss is text. I'm not entirely sure where the text section goes, but with the simple polygon block example, it seems we can just put the text section after the polygon face section.
To define the text, you must first provide the number of text objects to place on the geometry. Next, start listing out the text values. The first line of a text definition is the text string value. The next four lines after that represent the location/rotation transform for the text placement. To be honest, I'm not really sure how to interpret this. At some point I'll try to post some routines I built for reading and writing these rotation matrices, but in the mean time, to work with text, there is an easier way. Basically, just build your basic geometry, and manually place the text, save that out, and copy the transform matrix and use that.
So what we end up with with all this information should be a simple plain text file that we can feed into QUEST to build some simple rectangular box. Here it is:
I hope this has helped give some basic idea of how to build simple geometry files without using QUEST. Leave a comment if you have any questions about QUEST geometry that you'd like to discuss.