Need some help making my models flat to the screen...

Blitz3D Forums/Blitz3D Programming/Need some help making my models flat to the screen...

hollifd(Posted April) [#1]
I have a need to be able to open many models each day. I am finding that some of the models come in at odd angles (...not flat to the screen). Can anyone share some code with me that will allow me to click on a surface of the model and then have the code reorient the model flat to the screen? The models are always flat, like a plane with a small thickness (0.015 up to 0.500 inches thick). In a perfect world, I would like to make a keypress and then program waits for me to click on a surface of the part, and then the part reorients itself flat to the screen.

Thanks,
David


RemiD(Posted April) [#2]
Does your camera change its orientation or is always looking at +Z ?
If your camera changes its orientation, you can use tformvector(0,0,+1,camera,0) then tformedx(), tformedy(), tformedz(), to get the orientation vector of the camera. (same orientation than the direction of the linepick/camerapick you throw from the camera.
Then you can probably use aligntovector using the inverted vector to make your entity face the camera.
Not tested but it should work...


hollifd(Posted April) [#3]
Dang. You make it sound so simple. I haven't used any of those commands yet but I'll have a look in the Help section to see if I can figure out how it is done. My camera is not changing orientation. When I do move the camera, I can see that some of the models are coming in at odd orientations. These models are created by our design team and it seems there is no standardization. Most come in fine but some are at odd orientations and I need a way to deal with them. I do have a way to rotate them in one direction but I need a better way. Sounds simple enough but I need to do some more learning about the tools you mentioned above.

Thanks,
David


hollifd(Posted April) [#4]
Couldn't figure it out so I added some stupid code like this to make it work.

If KeyHit(11) = True Then
	If ItemToMove$ = "part" Then
		TurnEntity part, 0, 1, 0
	End If
End If
If KeyHit(10) = True Then
	If ItemToMove$ = "part" Then
		TurnEntity part, 0, -1, 0
	End If
End If
If KeyHit(9) = True Then
	If ItemToMove$ = "part" Then
		TurnEntity part, 1, 0, 0
	End If
End If
If KeyHit(8) = True Then
	If ItemToMove$ = "part" Then
		TurnEntity part, -1, 0, 0
	End If
End If


This is not ideal but will keep me going until I find a better way.


Floyd(Posted April) [#5]
This is similar to a "rocket exhaust" problem from four years ago. I suggested an idea and Kryzon turned it into a demo program in which a sphere represents the camera so you can see what is happening. He also offered an alternative approach, at the bottom of the thread.

Some Googling turned up the old thread. The site is not completely re-indexed yet. This is found on blitzmax.com but not on blitzbasic.com!

The original thread is here.

And the demo code:




Midimaster(Posted April) [#6]
Isn't he searching for the "orthographic projection" mode of Blitz3D? There is a command that flatten all your 3D object, so they look like 2D and have all the same orientation:

This command is not documented in the Blitz3D help: CameraProjMode()

but here:
http://www.blitzbasic.com/b3ddocs/command.php?name=CameraProjMode


RemiD(Posted April) [#7]
What i suggested will work consistently only if your models have the same orientation (in this case the flat shapes must be inverted from their default orientation (looking along +Z) to looking toward -Z. You can reoriente them using your modeling software, before you export them, or if they are not rigged, not skinned, not animated meshes (but rather rigid meshes) you can use rotatemesh() to change the default position of all vertices of the mesh.


hollifd(Posted April) [#8]
Thanks guys. Due to my limited mental abilities, I am using RotateMesh to adjust the models. I look at the models from 2 different views and use the rotatemesh commands to "flatten" the models to the screen. Most models are fine so this solution isn't killing us.

I also found some code in the archives for "centering" meshes. This has also helped tremendously since many of the models we are working with have origins far from the center of the meshes.

If anyone comes across some code that will allow selecting a surface of a model and point it "flat" to the screen, I would love to "borrow" it for the tool I am working on.

Thanks again,
David


Stevie G(Posted April) [#9]
Can I ask, are the rogue meshes rotated randomly on all axis' or just the pitch and yaw axis?


Floyd(Posted April) [#10]
I wondered about the same thing. "Flat to the screen" doesn't fully define the problem. After this is done the model can still be rolled, i.e. turned on the axis perpendicular to the screen.

There is another potential snag which is much more subtle. There was an example image posted a while back. It indicated that coordinates were right handed, typical of traditional mathematics and OpenGL graphics. But Blitz3D uses Direct3D style left handed coordinates. So you might be looking at a mirror image of the real thing.

In practice this would often make no real difference due to symmetry. Consider the following image, from the earlier post, and notice the coordinate system in the bottom left corner. Imagine the model reflected across the XY-plane so the raised section now points down. You can flip the finished item upside down, turning around the Y-axis. It now looks a lot like it should. If it had perfect left-right symmetry it would be back exactly where it started. But the symmetry is not perfect. Consider, for example, the little flap at the top of the diagram, at edge B3. This means it can't be put back to its proper state. It is a different shape and will not fit whatever larger assembly it is part of.




hollifd(Posted April) [#11]
I am a little embarrassed by my lack of knowledge about this sort of thing but I'll try to explain what I am seeing.

I bring in a flattened sheet metal part.
My intentions:
X axis - go from left to right on my screen
Y axis - go from top to bottom on my screen
Z axis - go from in to out on my screen

For the image above, I would expect the flattened sheet metal part to be completely facing the screen and not tilted to the left or right or front or back. When I look at the part on the screen, I cannot tell if it is completely flat or not so I move the camera around so that I can look at it from the left hand side view. When I look at the part from the side view, I can see some models are tilted. I see a line that is not horizontal or a line that has a thickness I know is too thick so it means the part is not oriented correctly. So I use the rotatemesh commands to take all of the tilt out. Then I can work with the part as normal.

Imagine dropping the flat sheet metal part on the floor and it rests flat against the floor. Then, stoop down, move your head to the left of the part and lay your left cheek on the ground and look at the part. I would expect to see a perfectly vertical line representing the flat part lying on the ground. Sometimes, I don't see a vertical line, I see the part is tilted as though when you dropped it to the ground, it landed on a rock and the part is tilted.

Once I have the part flat to the screen as I am calling it, then I need to be able to flip it (So I can see the back side) and rotate it clockwise or counter clockwise.

Silly explanation but maybe it will explain the problem I am having.

I am simulating a machine that bends sheet metal parts. My program views the machine from the top as if I was on the ceiling of the shop looking down at the machine. When I look down on the machine, I need to be able to see the complete width of the part. If the part is tilted a little left to right, then the width that I can see from the ceiling will be too narrow. Likewise, if the part is tilted a little front to back, the height of the part that I am seeing from the ceiling will be too short in the Y direction.

I need to be able to click on the part and then have the code ensure that the part is completely "flat" or "level". I am not sure how to describe that in terms that make sense to all of you.

If I drop the part onto the floor and it lands on a rock that keeps the part tilted, I need to have some code that kicks the rock out from under the part so that the part can lay flat again.

I am reading this and thinking it will be a miracle if anyone understands my goofy explanation.


...and yes....I am using CameraProjMode camera, 2

Thanks,
David


Floyd(Posted April) [#12]
I think the problem has been reasonably clear since the beginning. What is not clear is how to solve it.

A human eye and brain can look at a physical sheet of metal, or that image I just reposted, and immediately spot the "thin dimension", the one you want to align with the screen. This is not so obvious to a computer program. The model is just a pile of numbers with some structure. They are organized into groups of three which correspond to vertices. The vertices are then organized into groups of three, each representing an oriented triangle, i.e. there is a front and a back.

My general approach, some of which you have already done, would go something like this:

(Take this with a grain of salt, I've added a note at the end after step 5.)

1. Find the "center" of the mesh finding average x,y,z values for all the vertices. Use PositionMesh to make this the origin.

2. Deal with left/right handed coordinates. I don't know if this information is part of the 3D format you receive. You might have to resort to looking at a picture of what you are supposed to see and deciding whether you are seeing that or a mirror image. In case of a mirror image you would need to flip the mesh in some way.
For example ScaleMesh yourMesh, 1, -1, 1 would reflect in the X-Z plane by replacing each y with -y.

3. Now to orient it flat to the screen. It should be possible to automate this. Your program would look through the list of triangles to find the one with the biggest area. The idea is that the triangles embedded in the egde of the sheet are small and are not canditates for the "big, flat" side. Alternatively you could do this manually by clicking on a spot on the model and using PickedTriangle.
In any case you have a triangle to flatten to the screen. There would then be some math needed to find a vector perpendicular to this triangle. Use two edges as vectors and take their cross product.

4. Given this perpendicular vector you want to rotate the model to make the vector point at the camera. You probably want to turn the actual mesh rather than the entity it represents. I think a reasonable approach would be to use a pivot. Create the pivot as a child of the mesh so it inherits the orientation. Then use EntityParent to break the parent/child relationship. Use AlignToVector to aim a pivot axis, probably Z, at the camera. Then use RotateMesh to match the pitch/yaw/roll of the pivot. I'm a little vague on the details here, such as whether you need to aim toward or away from the camera. Experimentation should clear this up.

5. Once the model is flattened to the screen it will need to be rotated around the z-axis to get it "right side up". Again, this is not so easy to fully automate. It is probably easiest to have a "roll model" command to manually orient it so it is close to what is desired. The the program could look through model for triangle edges which are very close to vertical. It could then turn through the appropriate angle to make them exactly vertical.

Admittedly there is rather a lot to be done. But I don't see how that can be avoided.


I've just read through my entire post and the "flatten to screen" part is probably more trouble than it is worth. Your manual method of simply using keypresses to rotate the mesh into the the approximately correct orientation is easier. Then the program could tweak this, as suggested in step 5 above, to make it sufficiently exact. For example, find a large triangle with a nearly vertical edge. Turn the model to make this exactly vertical. Find a possible different triangle which is nearly flat to the screen, i.e. all z coordinates nearly equal. The model would have to be turned to make it more truly flat to the screen.

I can tell you from experience that these turns to make something "more exact" can very hard to calculate precisely. But it may be much easier to find an approximate solution which improves the situation. With the "rinse and repeat" approach of using these methods several times the model will quickly settle into the orientation you want.


hollifd(Posted April) [#13]
I was hoping there would be a simple solution. In our CAD system, it is 2 clicks to orient a model. It asks you to select a surface that you want to be the front and then select a surface you want to be the top. After making the two selections, the model is reoriented "flat to the screen" based on the selections.

Thanks for thinking about the problem. My current solution is not horrible. We just added a step to our process to view the part from the side view first. I added a button press to move the camera so that we could view from the left. I added button clicks to rotate the model in 1 deg increments each time you press the key and you can clearly see when the part has been oriented correctly or not.

I still have no solution for bending the flat part back into a formed part if you are looking for a challenge :)

Even though I am forced to work with a flat part only, this tool is a tremendous help since we are able to simulate much of the tooling setup and machine backstop settings using this program. In addition, I am able to take the information that is created by this software and generate a program that will actually run the machine that bends the sheet metal parts.

I really am thankful to all of you folks for helping me with my troubles along the way. I am amazed at how many smart people there are on this forum and at how many take the time to help others with their problems.

David


David