Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Go Back  Xtreme Visual Basic Talk > > > Exploring 3D graphics with VB.Net, but without using DirectX or XNA


Reply
 
Thread Tools Display Modes
  #41  
Old 02-25-2015, 09:04 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default It's only a "mistake" if it doesn't run..plus about other weird notions/possibilities


First off the "Perspective Scene 2.zip " gave me an error when I tried to run it saying it had a missing "app.config" file, so I patched in the one from the earlier perspective scene attachment and all is looking good.

Secondly..
Quote:
That is a mistake. The purpose of the base class is to provide a template for different types of 3D polyhedron.

That's not to say that everything is hunky dory. Now if you try to run both anims at the same time the group of solids will fly apart.The two rotations aren't combining properly, so it's still something I have to work out, maybe with Quaternions.

It was just a bit of "luck" that the problem didn't show up when the rotation center was at Scene.Origin.
What can I say - I'm a "lucky" code adjuster.
I agree that it's not something to permanently alter going forward,
but it did make you realize there was an issue with combining rotations (which I agree about).


Thirdly...
As regards "the purpose of the base class is to provide a template for different types of 3D polyhedron",
I agree that from a coders aspect that it makes sense to have a base class where you can use:
Code:
Inherits PolyhedronBase
..and not have to have identical sets of code included in all spawned polyhedra types (tetrahedron, cube, icosahedron...in the future, etc.).


However..

What if..."the purpose of the base class is to provide a template for..something else perhaps?

...and this is going to be hard for a programmer to synthesis..but from a design standpoint it sorta imposes a limitation.

How so?

It basically makes me choose (at the point where the New constructor is initialized), which type of platonic solid I'm adding to the scene.

What if I don't want to choose?
What is I reserve the right not to choose.

Look at this line:
Code:
Solids.Add(poly)
..which ends up being run if you use:
Scene1.AddPolyhedron(something)

However the Solids class doesn't really care what type of poly is being added to it (and neither does the Scene).

(..and by the way..I've already "transposed" in my mind the word "Solid" with a more generic reference to a "3D object")

From a designer standpoint this is a fantastic thing!

There is some "wiggle room".

I don't know if you feel this way, but I feel we're developing what could shape up into something like a 3D engine.

I know that sounds overly super-ambitious (that's why I didn't even want to bring it up at this point),
but have a maximal amount of flexibility is only going to benefit things down the road.

However let me come back to triangle fans (which I mentioned earlier).
What does that have to do with the PolyhedronBase class?

Here's my designer way thinking (and you may think I'm crazy,
or that it introduces a bad way of coding, but here goes..)

How could the code be adjusted so I didn't have to choose what type of Polyhedron I'm going to add poly to the Scene (or the Solids).

What if I just want to "add(poly)" and not choose.
How could this be accomplished?

A Polyhedron (when you come down to it) is just a set (or cluster) of 3D points,
(with the lines and the face tinting added on afterwards).

If I "genericized" the "Solids.Add(poly)" how many points would need to be added initially?

I'm thinking three - it would basically be a single triangle shaped face.

Or another way to think of it - a polygon where the three points that make up the polygon are all 3D points...points in 3D space.

That's so bizarre (I'm hearing you thinking as you read this).

But back to the triangle fan - if I did want my "poly" to be a triangle fan it would just be a matter
of adding the addition points to form the fan before showing it.

For that matter - all the polyhedra can be decomposed to series of these triangle shaped polygons,
(with polygon points being not 2D points, but 3D points).

So all 5 types of platonic solids could be formed after the add(poly) by just adding points.

So the steps would be:
1.) Add(poly) to Solids (and Scene)
2.) Choose what type of Polyhedron (or Platonic Solid) you want
3.) Have a routine that adds the extra points, then forms/creates the faces and edges
4.) Update the scene with the desired Polyhedrons actually drawn.

So, (and I realize this) there would be a bunch of 3D points (unrendered) hanging around in memory between steps 2 and 3.

I don't care (as long as they get garbage collected after the app stops running..even if steps 2 never gets around to happening).

I might even want (as a designer) to not draw a platonic solid..to just have a rotatable cluster of these 3D point polygons shown with faces tinted.

Or a cluster of quads made from combining (aligned/stuck together) two of these triangles made from three 3D points (with faces tinted).


This would lead to who knows what kind of zani-ness - meshes, perhaps? ( )

Anyway, don't know if you want to go down this particular path right now but just thought I would throw that out...


Some other stupid ideas I had:

Couldn't you "attach" (align?) a bunch of tetrahedrons to each of the dodecahedron faces.

Would would you get?
Hmmm..maybe some kind of stellated dodecahedron?


What if you started with a cube in the middle (as in most of the Perspective Scene demos so far).

Then you move the Tetrahedron to the bottom (with the base of the tetrahedron snuggled up to the bottom of the cube and the point of the the tetrahedron pointed downwards).

Then you placed a smaller cube on top of the same centered larger cube we started out with.

Then lose the edge lines and the faces.

What have you got?
Basically just a cluster of 3D points.

What good is that? (you might ask)

You got a starting point for rotoscoping.

I know this is the "old skool" way of "evolving" a 2D shape into a 3D shape,
but say you connected one set of vertically aligned set of 3D points using a bezier curve.
(Let's put aside/ignore the trickiness of setting the necessary bezier control points for the moment.)

Then you turn the point cluster slightly and connect the next set of vertically aligned 3D points.
Keep going until you have full set of bezier curves all the way around (360 degrees).

What you you have?
I'm thinking of the classic rotoscoped vase.
Here is the best picture I could find.

Of course such a vase, or any regular (symmetrical) 3D object, could also be done with triangle fans/strips.
If you decomposed it to small enough triangles it would appear to the naked eye to be "curvy" (even without using bezier curves or NURBS).

Anyway, maybe just my brain working overtime...
(thinking "poly" could be Polyhedra, PolyhedronBase or Polygon in 3D space,
..so Poly class instead of PolyhedronBase class, maybe?)

I do see great potential (to go in different directions) for the perspective warp scene code --even at this point.

Last edited by dotnetwrassler; 02-25-2015 at 09:43 AM.
Reply With Quote
  #42  
Old 02-25-2015, 02:19 PM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

Quote:
Originally Posted by dotnetwrassler View Post
First off the "Perspective Scene 2.zip " gave me an error when I tried to run it saying it had a missing "app.config" file, so I patched in the one from the earlier perspective scene attachment and all is looking good.

Secondly..


What can I say - I'm a "lucky" code adjuster.
I agree that it's not something to permanently alter going forward,
but it did make you realize there was an issue with combining rotations (which I agree about).


Thirdly...
As regards "the purpose of the base class is to provide a template for different types of 3D polyhedron",
I agree that from a coders aspect that it makes sense to have a base class where you can use:
Code:
Inherits PolyhedronBase
..and not have to have identical sets of code included in all spawned polyhedra types (tetrahedron, cube, icosahedron...in the future, etc.).


However..

What if..."the purpose of the base class is to provide a template for..something else perhaps?

...and this is going to be hard for a programmer to synthesis..but from a design standpoint it sorta imposes a limitation.

How so?

It basically makes me choose (at the point where the New constructor is initialized), which type of platonic solid I'm adding to the scene.

What if I don't want to choose?
What is I reserve the right not to choose.

Look at this line:
Code:
Solids.Add(poly)
..which ends up being run if you use:
Scene1.AddPolyhedron(something)

However the Solids class doesn't really care what type of poly is being added to it (and neither does the Scene).

(..and by the way..I've already "transposed" in my mind the word "Solid" with a more generic reference to a "3D object")

From a designer standpoint this is a fantastic thing!

There is some "wiggle room".

I don't know if you feel this way, but I feel we're developing what could shape up into something like a 3D engine.

I know that sounds overly super-ambitious (that's why I didn't even want to bring it up at this point),
but have a maximal amount of flexibility is only going to benefit things down the road.

However let me come back to triangle fans (which I mentioned earlier).
What does that have to do with the PolyhedronBase class?

Here's my designer way thinking (and you may think I'm crazy,
or that it introduces a bad way of coding, but here goes..)

How could the code be adjusted so I didn't have to choose what type of Polyhedron I'm going to add poly to the Scene (or the Solids).

What if I just want to "add(poly)" and not choose.
How could this be accomplished?

A Polyhedron (when you come down to it) is just a set (or cluster) of 3D points,
(with the lines and the face tinting added on afterwards).
We define a polyhedron in the first place as a set of flat polygonal faces complete with specific edges and vertices. The reason for doing it this way is that it's hard to work out the edges and faces from a bunch of 3D vertices. You can't just join up any two points because there will be countless wrong connections. You might use a 3D Convex Hull Algorithm (see Wikipedia) to wrap up a bunch of separate vertices but it would be limiting. You won't be able make something like a torus or a cube with a dent in it -- let alone a stellated icosahedron.

For the same reason, you can't just add a vertex to an existing solid and expect it to generate edges and faces automatically. You have to provide the geometrical know-how in some way.

The most practical way of working is to link up the vertices by eye, for example using the present program as a tool. This is what I am thinking of doing for the regular icosahedron: define all the vertices using the Wiki formulas, display them as a set of labelled dots (maybe with a new ID property in the Point3D class), rotate to see which dot connects to which, and code the resulting Face3Ds as the Icosahedron class.

It shouldn't be hard to organize multiple solids into composite objects. You could probably make a class for your Rubik's Cube and possibly one for the individual turnable layers.

Quote:
If I "genericized" the "Solids.Add(poly)" how many points would need to be added initially?

I'm thinking three - it would basically be a single triangle shaped face.

Or another way to think of it - a polygon where the three points that make up the polygon are all 3D points...points in 3D space.
No problemo. Here's a Triangle class:
Code:
Public Class Triangle
	Inherits PolyhedronBase
	Implements IDrawable

	Public Sub New(vertex1 As Point3D, vertex2 As Point3D, vertex3 As Point3D)
		Me.Faces.Add(New Face3D({vertex1, vertex2, vertex3}))
		Dim xTotal As Double = vertex1.X + vertex1.X + vertex3.X
		Dim yTotal As Double = vertex1.Y + vertex1.Y + vertex3.Y
		Dim zTotal As Double = vertex1.Z + vertex1.Z + vertex3.Z
		Me.Center = New Point3D(xTotal / 3, yTotal / 3, zTotal / 3)
	End Sub

End Class
Try adding a few to your scene. Don't forget to color both front and back!
Quote:
But back to the triangle fan - if I did want my "poly" to be a triangle fan it would just be a matter
of adding the addition points to form the fan before showing it.
If Cubes can be linked up into a group, so can Triangles. You'd have to figure out how to add new triangles: if you add a vertex, where does it connect to? But this should be soluble.
Quote:
For that matter - all the polyhedra can be decomposed to series of these triangle shaped polygons,
(with polygon points being not 2D points, but 3D points).

So all 5 types of platonic solids could be formed after the add(poly) by just adding points.

So the steps would be:
1.) Add(poly) to Solids (and Scene)
2.) Choose what type of Polyhedron (or Platonic Solid) you want
3.) Have a routine that adds the extra points, then forms/creates the faces and edges
4.) Update the scene with the desired Polyhedrons actually drawn.
Easily said, but step 3 is the problem. What routine?
Quote:
So, (and I realize this) there would be a bunch of 3D points (unrendered) hanging around in memory between steps 2 and 3.

I don't care (as long as they get garbage collected after the app stops running..even if steps 2 never gets around to happening).
Point3Ds are tiny, you could have millions of them without worrying. All the process memory is released when the application closes. It may not get cleared up until later, but that's none of your business.

Quote:
I might even want (as a designer) to not draw a platonic solid..to just have a rotatable cluster of these 3D point polygons shown with faces tinted.
Again: where do you get the faces?
Quote:
Or a cluster of quads made from combining (aligned/stuck together) two of these triangles made from three 3D points (with faces tinted).

This would lead to who knows what kind of zani-ness - meshes, perhaps? ( )

Anyway, don't know if you want to go down this particular path right now but just thought I would throw that out...
No thank you.

Quote:
Some other stupid ideas I had:

Couldn't you "attach" (align?) a bunch of tetrahedrons to each of the dodecahedron faces.

Would would you get?
Hmmm..maybe some kind of stellated dodecahedron?
It's possible, but won't get very far without applying geometrical knowledge.

Quote:
What if you started with a cube in the middle (as in most of the Perspective Scene demos so far).

Then you move the Tetrahedron to the bottom (with the base of the tetrahedron snuggled up to the bottom of the cube and the point of the the tetrahedron pointed downwards).

Then you placed a smaller cube on top of the same centered larger cube we started out with.

Then lose the edge lines and the faces.

What have you got?
Basically just a cluster of 3D points.

What good is that? (you might ask)

You got a starting point for rotoscoping.
.
I know this is the "old skool" way of "evolving" a 2D shape into a 3D shape,
but say you connected one set of vertically aligned set of 3D points using a bezier curve.
(Let's put aside/ignore the trickiness of setting the necessary bezier control points for the moment.)

Then you turn the point cluster slightly and connect the next set of vertically aligned 3D points.
Keep going until you have full set of bezier curves all the way around (360 degrees).

What you you have?
I'm thinking of the classic rotoscoped vase.
Here is the best picture I could find.

Of course such a vase, or any regular (symmetrical) 3D object, could also be done with triangle fans/strips.
If you decomposed it to small enough triangles it would appear to the naked eye to be "curvy" (even without using bezier curves or NURBS).

Anyway, maybe just my brain working overtime...
(thinking "poly" could be Polyhedra, PolyhedronBase or Polygon in 3D space,
..so Poly class instead of PolyhedronBase class, maybe?)

I do see great potential (to go in different directions) for the perspective warp scene code --even at this point.
Groan.
Reply With Quote
  #43  
Old 02-26-2015, 10:44 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Mostly soluble...

Thanks for the extended reply.

Even though there was a bit of groaning at the end it sounds like most of what I thinking about was not beyond the realm of possibility --which is good.

Quote:
Originally Posted by boops boops
For the same reason, you can't just add a vertex to an existing solid and expect it to generate edges and faces automatically. You have to provide the geometrical know-how in some way.
This is what is making it hard to complete the last two platonic solids - the octahedron and the icosahedron..I realize that.

I still want the 3D Points scoped up to the project level, but I understand from what you are saying that
adding (forming) faces and edges from those points is not a trivial thing.

Right now I'm putting that aside to concentrate on a simple () way of dragging a point in 3D space with a 2D mouse.

The next step towards that is to have some code such that the circles around the 3D corners/vertices change color from gold to red as they are moused over.



From an user interface perspective to be able to do something to edit/change the shape of any 3D object at runtime is important.

I realize that moving a 3D point may "break" the edges and faces,
but working toward a way to manipulate those points in some fashion is still a important priority going forward.

Don't have time to write much else right now.

Hopefully you will still keep exploring quaternions for rotation (I'm still doing experimental mash-ups
trying to merge your Perspective Scene code with
the earlier working quaternion code --that was originally attached to post #4 of this thread).
Reply With Quote
  #44  
Old 02-26-2015, 02:05 PM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

Quote:
Originally Posted by dotnetwrassler View Post
Thanks for the extended reply.

Even though there was a bit of groaning at the end it sounds like most of what I thinking about was not beyond the realm of possibility --which is good.

This is what is making it hard to complete the last two platonic solids - the octahedron and the icosahedron..I realize that.
On the contrary, an octahedron should be relatively easy, and I said how I would go about doing an icosahedron. It would just be a chore. After all, Platonic solids aren't much use once you've done them, apart from the cube and maybe the tetrahedron. Romantic solids, now that's a different matter...

Quote:
I still want the 3D Points scoped up to the project level, but I understand from what you are saying that
adding (forming) faces and edges from those points is not a trivial thing.

Right now I'm putting that aside to concentrate on a simple () way of dragging a point in 3D space with a 2D mouse.

The next step towards that is to have some code such that the circles around the 3D corners/vertices change color from gold to red as they are moused over.

From an user interface perspective to be able to do something to edit/change the shape of any 3D object at runtime is important.

I realize that moving a 3D point may "break" the edges and faces,
but working toward a way to manipulate those points in some fashion is still a important priority going forward.
The code I posted provides one way to drag the vertices in 3d. You just turn the view by running the anim momentarily. Then you can drag the vertex in a different 3d direction. You can think about different styles of interaction, but I don't want to get too involved in that because it depends on your application. Any code that I post here is just a demo of a technique and/or a learning process for myself.

In the present program, all the vertices of a solid remain correctly connected to one another when dragged. The only thing that "breaks" is when you drag a vertex out of the plane so that a face is no longer flat. The program could insert a new edge along the crease to divide it into triangles, or might be simpler just to turn the whole thing into triangles from the outset.

BB

Last edited by boops boops; 02-26-2015 at 02:17 PM.
Reply With Quote
  #45  
Old 03-01-2015, 02:08 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Dragging the vertices in 3d..and rendering the octahedron platonic solid

Quote:
Originally Posted by boops boops
The code I posted provides one way to drag the vertices in 3d...Any code that I post here is just a demo of a technique and/or a learning process for myself.
Yes!
Being able to drag the whole polyhedron or just drag a single 3D point to distort the 3D shape
allows a whole new level of interactivity to the scene.

(see the attached image, "screenshot_PerpsectiveScene2_with_Point3D_dragging_points_reshaping.j pg"
for what you can do with some drag distortion/re-shaping))

Quote:
Originally Posted by boops boops
The program could insert a new edge along the crease to divide it into triangles,
or might be simpler just to turn the whole thing into triangles from the outset.
Indeed, there are still many possibilities left to explore.

Quote:
Originally Posted by boops boops
On the contrary, an octahedron should be relatively easy..
No it's still not easy (for me).

However, I'm still working toward that goal...playing around with experimentally plugging in different numbers
for the needed bottom point I did manage to get to a 3D diamond shape (hexahedron?).

I know it's not a true octahedron, but it just needs one more point --so I'll keep working on it.

Some other octahedron info I found:
http://userpages.umbc.edu/~squire/im...ctahedron3.jpg
http://www7b.biglobe.ne.jp/~kcy05t/zu/oxx2.gif
http://www.vbexplorer.com/VBExplorer...fTriangles.asp

The last page implements the vertices with this code:
Code:
' Initialize the objects we will display.
Private Sub InitializeObjects()
    MakeTriangle 0, 10, 0, 0, 0, 10, 10, 0, 0
    MakeTriangle 0, 10, 0, 10, 0, 0, 0, 0, -10
    MakeTriangle 0, 10, 0, 0, 0, -10, -10, 0, 0
    MakeTriangle 0, 10, 0, -10, 0, 0, 0, 0, 10
    MakeTriangle 0, -10, 0, 0, 0, -10, 10, 0, 0
    MakeTriangle 0, -10, 0, 10, 0, 0, 0, 0, 10
    MakeTriangle 0, -10, 0, 0, 0, 10, -10, 0, 0
    MakeTriangle 0, -10, 0, -10, 0, 0, 0, 0, -10
End Sub

This page lists the vertices as:
( 1, 0, 0)
( 0, 1, 0)
( 0, 0, 1)
(-1, 0, 0)
( 0, -1, 0)
( 0, 0, -1)


*****************************************

Re: icosahedron

I also found this page which seems to give a simplified (for boops boops, not for me) way to calculate all the vertices of an icosahedron:
a = ( 0, 0, Z1)
b = ( 0, R, Z2)
c = ( Cx, Cy, Z2)
d = ( S/2, -H, Z2)
e = (-S/2, -H, Z2)
f = ( -Cx, Cy, Z2)
g = ( 0, -R, -Z2)
h = ( -Cx, -Cy, -Z2)
i = (-S/2, H, -Z2)
j = ( S/2, H, -Z2)
k = ( Cx, -Cy, -Z2)
l = ( 0, 0, -Z1)

where:
S = the side length (given)
t1 = 2 * Pi / 5
t2 = Pi / 10
t4 = Pi / 5
t3 = -3 * Pi / 10
R = (S/2) / Sin(t4)
H = Cos(t4) * R
Cx = R * Cos(t2)
Cy = R * Sin(t2)

H1 = Sqrt(S * S - R * R)
H2 = Sqrt((H + R) * (H + R) - H * H)
Z2 = (H2 - H1) / 2
Z1 = Z2 + H1


There's also some explanatory diagrams and the all important "Figure 4.2. An icosahedron with nodes labeled."

Hopefully this will help toward finally figuring out the how to do an icosahedron in VB.Net.

The only thing that I could find that listed the specific numbers for the icosahedron vertices was this page which had this info:

Icosahedron, Faces: 20, Vertices: 60

-0.26286500f, 0.0000000f, 0.42532500f
0.0000000f, -0.42532500f, 0.26286500f
0.26286500f, 0.0000000f, 0.42532500f
-0.26286500f, 0.0000000f, 0.42532500f
-0.42532500f, -0.26286500f, 0.0000000f
0.0000000f, -0.42532500f, 0.26286500f
0.26286500f, 0.0000000f, 0.42532500f
0.0000000f, 0.42532500f, 0.26286500f
-0.26286500f, 0.0000000f, 0.42532500f
0.26286500f, 0.0000000f, 0.42532500f
0.42532500f, 0.26286500f, 0.0000000f
0.0000000f, 0.42532500f, 0.26286500f
0.26286500f, 0.0000000f, 0.42532500f
0.42532500f, -0.26286500f, 0.0000000f
0.42532500f, 0.26286500f, 0.0000000f
-0.26286500f, 0.0000000f, -0.42532500f
0.0000000f, 0.42532500f, -0.26286500f
0.26286500f, 0.0000000f, -0.42532500f
-0.26286500f, 0.0000000f, -0.42532500f
-0.42532500f, 0.26286500f, 0.0000000f
0.0000000f, 0.42532500f, -0.26286500f
-0.26286500f, 0.0000000f, -0.42532500f
-0.42532500f, -0.26286500f, 0.0000000f
-0.42532500f, 0.26286500f, 0.0000000f
0.26286500f, 0.0000000f, -0.42532500f
0.0000000f, -0.42532500f, -0.26286500f
-0.26286500f, 0.0000000f, -0.42532500f
0.26286500f, 0.0000000f, -0.42532500f
0.42532500f, -0.26286500f, 0.0000000f
0.0000000f, -0.42532500f, -0.26286500f
0.0000000f, 0.42532500f, 0.26286500f
0.42532500f, 0.26286500f, 0.0000000f
0.0000000f, 0.42532500f, -0.26286500f
0.0000000f, 0.42532500f, 0.26286500f
-0.42532500f, 0.26286500f, 0.0000000f
-0.26286500f, 0.0000000f, 0.42532500f
0.0000000f, 0.42532500f, -0.26286500f
0.42532500f, 0.26286500f, 0.0000000f
0.26286500f, 0.0000000f, -0.42532500f
0.0000000f, 0.42532500f, -0.26286500f
-0.42532500f, 0.26286500f, 0.0000000f
0.0000000f, 0.42532500f, 0.26286500f
0.0000000f, -0.42532500f, 0.26286500f
0.42532500f, -0.26286500f, 0.0000000f
0.26286500f, 0.0000000f, 0.42532500f
0.0000000f, -0.42532500f, 0.26286500f
-0.42532500f, -0.26286500f, 0.0000000f
0.0000000f, -0.42532500f, -0.26286500f
0.0000000f, -0.42532500f, -0.26286500f
0.42532500f, -0.26286500f, 0.0000000f
0.0000000f, -0.42532500f, 0.26286500f
0.0000000f, -0.42532500f, -0.26286500f
-0.42532500f, -0.26286500f, 0.0000000f
-0.26286500f, 0.0000000f, -0.42532500f
0.42532500f, 0.26286500f, 0.0000000f
0.42532500f, -0.26286500f, 0.0000000f
0.26286500f, 0.0000000f, -0.42532500f
-0.42532500f, 0.26286500f, 0.0000000f
-0.42532500f, -0.26286500f, 0.0000000f
-0.26286500f, 0.0000000f, 0.42532500f


Of course this is related to use "Vector3" structure (an XNA/DirectX thing),
but who knows..might still be helpful to mention it in passing..

Eventually we may get to drawing arcs between 3D Points.
(It's already been brought up about trying to achieve a sphere).

This StackOverFlow thread has a nice animated gif in one of the answers that shows how a set of line segments (making up a straight line) can be made to "bulge out" into a set of arcs.

It goes on to say:
Quote:
This process can be extended into three dimensions, in which case you get a sphere rather than a circle.
Just add a dz component to the normalize function.
Yeah, right..the normalize function...

Lastly, here's a couple new terms of the week:

1.) Kleetope
Defined as:
Quote:
In geometry and polyhedral combinatorics, the Kleetope of a polyhedron or higher-dimensional convex polytope P
is another polyhedron or polytope PK formed by replacing each facet of P with a shallow pyramid.
The Kleetope Wikipedia link above has some diagrams showing the different triakis versions of the 5 platonic solids.

2.) Polytopes
Defined as:
Quote:
In elementary geometry, a polytope is a geometric object with flat sides,
and may exist in any general number of dimensions n as an n-dimensional polytope or n-polytope.
For example a two-dimensional polygon is a 2-polytope and a three-dimensional polyhedron is a 3-polytope.
The Wikipedia article also goes on to say:
Quote:
The term polytope is nowadays a broad term that covers a wide class of objects, and different definitions are attested in mathematical literature.
Many of these definitions are not equivalent, resulting in different sets of objects being called polytopes.
They represent different approaches to generalizing the convex polytopes to include other objects with similar properties.
Will this thread ever get around to "convex polytopes"..probably not..but again...I'll mention it in passing since the only thing I could find in the MSDN
was this Microsoft PowerPoint presentation on XNA collisions that mentions DOPs (Discrete Oriented Polytopes).





edit1(later):
PS3b_Octahedron_attempt2 attached (with screenshot that includes 4 of the 5 platonic solids).

Last edited by dotnetwrassler; 03-01-2015 at 03:31 PM.
Reply With Quote
  #46  
Old 03-06-2015, 12:48 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default 3D wireframe sphere with tinted color fill

In thinking about generating the points to form a sphere, I looked at recycling the code attached to this forum post.

Right now it uses 'Public Class Point3' instead of 'Public Class Point3D' from the Perspective scene attachments,
but they look pretty close.

In terms of the Perspectives Scene's 'Public Structure Edge3D',
the sphere code uses 'pta',

Then for a 'face' (as defined by the Perspective Scene's 'Public Class Face3D'),
there is a 'ptf' array which feeds in the pta array 'edges' using:
Code:
Private transparencyNumber As Integer = 96
...
Dim pta As PointF(,) = New PointF(pts.GetLength(0) - 1, pts.GetLength(1) - 1) {}
For i As Integer = 0 To pts.GetLength(0) - 1
	For j As Integer = 0 To pts.GetLength(1) - 1
		pts(i, j).Transform(m)
		pta(i, j) = Point2D(New PointF(pts(i, j).X, pts(i, j).Y))
	Next
Next
Dim ptf As PointF() = New PointF(3) {}
For i As Integer = 1 To pts.GetLength(0) - 1
	For j As Integer = 1 To pts.GetLength(1) - 1
		ptf(0) = pta(i - 1, j - 1)
		ptf(1) = pta(i, j - 1)
		ptf(2) = pta(i, j)
		ptf(3) = pta(i - 1, j)
		Dim alphabrush1 As New SolidBrush(Color.FromArgb(transparencyNumber, _
			               rnd.Next(0, 256), _
				       rnd.Next(0, 256), _
				       rnd.Next(0, 256)))	
		g.FillPolygon(alphabrush1, ptf)
		g.DrawPolygon(Pens.Black, ptf)
	Next
Next
So overall I think there is a possibility that this sphere code could be
"adapted" (merged or refactored?) to use the classes from Perspective Scene.

I've left in some extra commented out code to play around with the tinting,
as well as some comments on the Translate3 function that could be use to move the
sphere around either with buttons or, maybe even, by dragging.

The chief limitation of the sphere coordinates code is there is no way to rotate the sphere end-over-end,
(unless you want to deal with matrix rotation, which I certainly do not).


I also found this page, which has a nice image:
Quote:
that shows that the vertices of an icosahedron are the corners of three orthogonal rectangles..
It's the same image buried on the Wikipedia Icosahedron page,
but there is also (additionally) this image which relates the vertices to the faces:
Code:
01	// create 20 triangles of the icosahedron
02	var faces = new List<TriangleIndices>();
03	 
04	// 5 faces around point 0
05	faces.Add(new TriangleIndices(0, 11, 5));
06	faces.Add(new TriangleIndices(0, 5, 1));
07	faces.Add(new TriangleIndices(0, 1, 7));
08	faces.Add(new TriangleIndices(0, 7, 10));
09	faces.Add(new TriangleIndices(0, 10, 11));
10	 
11	// 5 adjacent faces
12	faces.Add(new TriangleIndices(1, 5, 9));
13	faces.Add(new TriangleIndices(5, 11, 4));
14	faces.Add(new TriangleIndices(11, 10, 2));
15	faces.Add(new TriangleIndices(10, 7, 6));
16	faces.Add(new TriangleIndices(7, 1, 8));
17	 
18	// 5 faces around point 3
19	faces.Add(new TriangleIndices(3, 9, 4));
20	faces.Add(new TriangleIndices(3, 4, 2));
21	faces.Add(new TriangleIndices(3, 2, 6));
22	faces.Add(new TriangleIndices(3, 6, 8));
23	faces.Add(new TriangleIndices(3, 8, 9));
24	 
25	// 5 adjacent faces
26	faces.Add(new TriangleIndices(4, 9, 5));
27	faces.Add(new TriangleIndices(2, 4, 11));
28	faces.Add(new TriangleIndices(6, 2, 10));
29	faces.Add(new TriangleIndices(8, 6, 7));
30	faces.Add(new TriangleIndices(9, 8, 1));
The vertices creation goes simply:
Code:
01	// create 12 vertices of a icosahedron
02	var t = (1.0 + Math.Sqrt(5.0)) / 2.0;
03	 
04	addVertex(new Point3D(-1,  t,  0));
05	addVertex(new Point3D( 1,  t,  0));
06	addVertex(new Point3D(-1, -t,  0));
07	addVertex(new Point3D( 1, -t,  0));
08	 
09	addVertex(new Point3D( 0, -1,  t));
10	addVertex(new Point3D( 0,  1,  t));
11	addVertex(new Point3D( 0, -1, -t));
12	addVertex(new Point3D( 0,  1, -t));
13	 
14	addVertex(new Point3D( t,  0, -1));
15	addVertex(new Point3D( t,  0,  1));
16	addVertex(new Point3D(-t,  0, -1));
17	addVertex(new Point3D(-t,  0,  1));
All of this is based on C# coding, but is a lot more straightforward than a lot of non-DotNet code I've seen/found.

The only different between the 3 'orthogonal' rectangle faces used here (to calculate/form the icosahedron vertices),
is that they have a 2 to 1 rectangular ratio rather than
the one to one ratio found in the perfectly square faces of the cuboid for the Perspective Scene code.
Attached Images
File Type: jpg screenshot-3D wireframe sphere with tinted color fill.JPG (42.6 KB, 5 views)
Attached Files
File Type: zip 3D wireframe sphere with tinted color fill.zip (53.4 KB, 15 views)

Last edited by dotnetwrassler; 03-06-2015 at 12:59 AM.
Reply With Quote
  #47  
Old 03-08-2015, 06:24 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default All 5 platonic shapes - including Icosahedron

This definitely took a non-trivial amount of time to code,
but here is the new Icosahedron Class:

Quote:
Public Class Icosahedron
Inherits PolyhedronBase
Public Sub New(radius As Double, center As Point3D)
Const Pi As Double = System.Math.PI
Dim s = radius * 2
Dim t1 = 2 * Pi / 5
Dim t2 = Pi / 10
Dim t3 = -3 * Pi / 10
Dim t4 = Pi / 5
Dim R = (s / 2) / System.Math.Sin(t4)
Dim H = System.Math.Cos(t4) * R
Dim H1 = System.Math.Sqrt(s * s - R * R)
Dim H2 = System.Math.Sqrt((H + R) * (H + R) - H * H)
Dim Cx = R * System.Math.Cos(t2)
Dim Cy = R * System.Math.Sin(t2)
Dim Z2 = (H2 - H1) / 2
Dim Z1 = Z2 + H1

Dim vtx0 As New Point3D(0, 0, Z1) 'With {.id = 0}, point a
Dim vtx1 As New Point3D(0, R, Z2) 'With {.id = 1}, point b
Dim vtx2 As New Point3D(Cx, Cy, Z2) 'With {.id = 2}, point c
Dim vtx3 As New Point3D(s / 2, -H, Z2) 'With {.id = 3}, point d
Dim vtx4 As New Point3D(-s / 2, -H, Z2) 'With {.id = 4}, point e
Dim vtx5 As New Point3D(-Cx, Cy, Z2) 'With {.id = 5}, point f
Dim vtx6 As New Point3D(0, -R, -Z2) 'With {.id = 6}, point g
Dim vtx7 As New Point3D(-Cx, -Cy, -Z2) 'With {.id = 7}, point h
Dim vtx8 As New Point3D(-s / 2, H, -Z2) 'With {.id = 8}, point i
Dim vtx9 As New Point3D(s / 2, H, -Z2) 'With {.id = 9}, point j
Dim vtx10 As New Point3D(Cx, -Cy, -Z2) 'With {.id = 10}, point k
Dim vtx11 As New Point3D(0, 0, -Z1) 'With {.id = 11}, point l

' Icosahedron(vertices) should be the following Point3Ds (points in 3D space):
'0, 0, 0.951056516295154
'0, 0.85065080835204, 0.42532540417602
'0.809016994374947, 0.262865556059567, 0.42532540417602
'0.5, -0.688190960235587, 0.42532540417602
'-0.5, -0.688190960235587, 0.42532540417602
'-0.809016994374947, 0.262865556059567, 0.42532540417602
'0, -0.85065080835204, 0.42532540417602
'-0.809016994374947, -0.262865556059567, 0.42532540417602
'-0.5, -0.688190960235587, 0.42532540417602
'0.5, -0.688190960235587, 0.42532540417602
'0.809016994374947, -0.262865556059567, 0.42532540417602
'0, 0, -0.951056516295154


Dim faces As New List(Of Face3D)
'top section
faces.Add(New Face3D({vtx0, vtx1, vtx2})) 'a,b,c
faces.Add(New Face3D({vtx0, vtx2, vtx3})) 'a,c,d
faces.Add(New Face3D({vtx0, vtx3, vtx4})) 'a,d,e
faces.Add(New Face3D({vtx0, vtx5, vtx4})) 'a,e,f
faces.Add(New Face3D({vtx0, vtx5, vtx1})) 'a,f,b
'middle section
faces.Add(New Face3D({vtx2, vtx1, vtx9})) 'c,b,j
faces.Add(New Face3D({vtx2, vtx9, vtx10})) 'c,j,k
faces.Add(New Face3D({vtx3, vtx2, vtx10})) 'd,c,k
faces.Add(New Face3D({vtx3, vtx10, vtx6})) 'd,k,g
faces.Add(New Face3D({vtx4, vtx3, vtx6})) 'e,d,g
faces.Add(New Face3D({vtx4, vtx7, vtx6})) 'e,h,g
faces.Add(New Face3D({vtx5, vtx4, vtx7})) 'f,e,h
faces.Add(New Face3D({vtx5, vtx7, vtx8})) 'f,h,i
faces.Add(New Face3D({vtx1, vtx5, vtx8})) 'b,f,i
faces.Add(New Face3D({vtx1, vtx8, vtx9})) 'b,i,j
'bottom section
faces.Add(New Face3D({vtx11, vtx10, vtx9})) 'l,k,j
faces.Add(New Face3D({vtx11, vtx10, vtx6})) 'l,k,g
faces.Add(New Face3D({vtx11, vtx6, vtx7})) 'l,g,h
faces.Add(New Face3D({vtx11, vtx7, vtx8})) 'l,h,i
faces.Add(New Face3D({vtx11, vtx8, vtx9})) 'l,i,j
MyBase.Faces = faces.ToList
MyBase.Center = center
End Sub

End Class
Working code attached below (with screenshot)
There is a gif diagram inside the project showing where vertices a thru l are located.

I am willing to guarantee you will not find this VB.Net code snippet anywhere else on the entire Internet!

I'll also throw in a screenshot of things to come - ramping up the number of vertices and triangle faces into the thousands..
(I'm sure boops boops can't wait! )

Last edited by dotnetwrassler; 03-08-2015 at 07:08 PM.
Reply With Quote
  #48  
Old 03-09-2015, 07:18 PM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

Hi dnw,

Let me be the first to congratulate you on completing the Platonic 5! Your Icosahedron is perfect: Plato would be proud of you.

The Octahedron looks great but the code needs some cleaning up. Firstly, you defined all the faces twice: I commented everything with "centerQuad" and it didn't make a jot of difference: still looks good. Then I noticed you introduced a fudge factor with Dim ApexPointOffset = 20. Maybe that gave you the right shape, but it won't scale. The formulae for the vertices are actually simpler than you realized (that's the advantage of knowing a bit of 3D geometry). They are corrected in the code attached below so now it's a genuine Platonic regular Octahedron when you use the single size argument.

For the Icosahedron, I've cleared out the commented-out stuff. Now both these polyhedra can have a permanent place in the Solids folder.

You may have noticed that the Point3Ds had a commented-out "ID" field in my Dodecahedron code. I had made a special version of the Point3D with an ID label in order to sort out the faces; but I seem to have mislaid it. But I should be able to recreate it without too many problems. It will be useful to have a souped-up version of the Point3D as an aid to designing new shapes. It could be labelled with an ID (text), have dot markers with Z scaling and custom colors, and optional X, Y and Z value reporting. It could also have the dragging code built in, and possibly a tool for marking faces from the points. The class would Inherit from Point3D: let's call it an EditablePoint3D.

I noticed something very curious about your 5-solid scene. When you try running both rotations at the same time, it's only the Cube which goes off into a deviant orbit. I can't be sure but it suggests to me that there may be nothing wrong with the angle maths, just a bug somewhere in the Cube code. I'll look into it. EDIT: alas it is not so. The cube was the only shape with multiple rotation axes. I gave the Tetrehedron an extra Y rotation and it immediately went AWOL. So some harder work is needed.

I haven't downloaded your Sphere code yet, but it looks promising. That definitely needs a place in the Solids box. I assume we are not limiting that to the Platonic solids.

Unfortunately I won't have a lot of time for this thread in the next few months. It takes quite a lot of time just to read your long messages, let alone follow up all the links. That's what my "groan" was about in your previous post. But don't let me put you off, you are making some good discoveries.

BB
Attached Files
File Type: zip Oct+Icos.zip (1.7 KB, 13 views)

Last edited by boops boops; 03-09-2015 at 07:25 PM.
Reply With Quote
  #49  
Old 03-12-2015, 01:11 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Re: ico/oct update..and a bit about future file handling code..

Quote:
Originally Posted by boops boops
It takes quite a lot of time just to read your long messages, let alone follow up all the links.
Thanks for sticking with this thread despite my looooonnnnnngggg posts.

You may not think so, but this thread may have historical interest (if the xvbt forum doesn't sink entirely under the weight of all the adverts),
so I really want to try and document the process as things go along.

The thread seeks to bring together the "state of the art" in terms of everything I've been able to research online up to this point for this topic.

If this were a Github project I'd have most of the verbiage stuffed away in commit comments.



Quote:
They are corrected in the code attached below so now it's a genuine Platonic regular Octahedron when you use the single size argument.
For the Icosahedron, I've cleared out the commented-out stuff. Now both these polyhedra can have a permanent place in the Solids folder.
Thanks for the cleaned-up code attached in your previous post.

Note to others:
The "Oct+Icos.zip " (attached in post #48) does not include all the Perspective Shape files and is only an update that would need to be merged into either the "PS5-All_5_platonic_shapes.zip" code attached to post #47, or the original "Perspective Scene 2.zip" attached to post #40.



Quote:
I noticed something very curious about your 5-solid scene. When you try running both rotations at the same time, it's only the Cube which goes off into a deviant orbit. I can't be sure but it suggests to me that there may be nothing wrong with the angle maths, just a bug somewhere in the Cube code. I'll look into it. EDIT: alas it is not so. The cube was the only shape with multiple rotation axes. I gave the Tetrahedron an extra Y rotation and it immediately went AWOL. So some harder work is needed.
So the cube "bug" is due to an uncorrectly handled Y rotation?
That leaves me I'm wondering what kind tweak would be need to fix this?

Quote:
I assume we are not limiting that to the Platonic solids.
That is correct!
I already have some preliminary vertices/Point3Ds and face mapping for some other 3D primitives like:
- A Cone
- A Torus
- A Cylinder

The "awkwardness" of the Sphere demo is that is not adhering to the way the Perspective Scene is set up at all.

It basically needs a major re-factoring before it can be merged with the existing BBDP (boops boops, dotnetwrassler, passel) codebase (as you'll see when you take a look at it).
I personally think it was intended to be used/integrated with the use of 3D meshes rather than the way Perspective Scene works up to this point.


Quote:
Unfortunately I won't have a lot of time for this thread in the next few months.
This is a "side project" for me as well,
but I know you'll try to stop by when you can to try and keep me from going too far "off the tracks".


Quote:
You may have noticed that the Point3Ds had a commented-out "ID" field in my Dodecahedron code. I had made a special version of the Point3D with an ID label in order to sort out the faces; but I seem to have mislaid it. But I should be able to recreate it without too many problems...The class would Inherit from Point3D: let's call it an EditablePoint3D.
Yes, I wondered about that?!

An EditablePoint3D class would be highly desirable if you can find the time to recreate it.
I can just imagine the many goodies stashed away (unpublished) on the boops boops hard drive(s).

Hopefully any 3D related code will eventually make its way to attachment(s) in later posts for this thread.


Here's one "feature" I thought of, which I have no idea to implement (but would be desirable).

Right now we can detect whether the mouse is over (and ready to drag) a full solid or just a point.

Great.

But what about an "edge detection" routine that would trigger a boolean if the mouse is over a line between the faces.

One could then use that boolean to:
1.) drag the line (with the two vertices at either end in tow) OR
2.) possibly insert a 3D point in a mouse down event (maybe right click mouse down) that could do a triangulation bisection along that edge that would split the face.

Pretty crazy idea, huh?



Re: Design time file loading and saving

I am working with every spare moment I can get to merge the .3DS model file loading code into the BBDP code base.

I consider it absolutely necessary to add reading/writing to disk for design-time "persistence" if the project is to have any chance of being truly useful in a general way to non-programmers (where everything isn't hard-coded at runtime).

However, I really do not care if the file format is the .3ds (a 3D Studio Max) format,
or some other type of standard format (like Collada/SketchupPro's DAE, AutoCad's dxf/dwg (which I'm sure Gruff would like), Blenders ever-morphing .blend format,
or some custom format).

I went with .3DS straightaway because (of course) a working attachment of VB.Net code for loading and display of such files already exists (has been published) on this forum.

Anyone who has some thoughts on this, please feel free to post suggestions.

Just thinking about this gives me the heebie jeebies though...scaling factors, camera orientations, lighting/shader effects support (including Blender Cycle-style "bounce lighting"), UV wrapping, bones/forward/inverse kinetics, caustics, Maya-type soft body dynamic constraint attributes (including emitted particle springs), inter-mesh intersection booleans, model nesting, multi-layer and multiple "scene" support support, animation timelining, etc..

--and that list doesn't even include real world physic modelling.

Yes, it can be a huge "swamp" of expectations to wade into.

So to anyone who is following this thread (without posting) please know the initial "saveTo" and "readFrom" file code will be very humble.

Maybe even something as basic as using the forum's posted working VB.Net .ini file "sampler" code.

Last edited by dotnetwrassler; 03-12-2015 at 01:35 PM.
Reply With Quote
  #50  
Old 03-16-2015, 09:17 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Towards saving a .3DS model into an ini file format and ContextSwitchDeadLock error

First off --sorry for yet another lllloooonnngggg post.

I'm sure everyone knows what ini files are..but just in case you don't, here's a Wikipedia link explaining a little bit:
http://en.wikipedia.org/wiki/INI_file

I actually ended up using "IniFile_Sampler_rev1.zip" from this post as the starting point for trying to do a .3DS file to ini file convertor

Here's the initial difficulty/challenge - IEnumerator.

I sure all those who are experts in System.Collections Namespaces know that it's one of the "Interface" types (along with IEnumerable) and
that inheriting from IEnumerable means your class returns an IEnumerator object.

My particular difficulty was that the .3DS file loader code (that I need to merge into the Ini sampler code) only uses simple string arrays.



So how do convert an ordinary run-of-the-mill array into something "exotic" as using an IEnumerator collection.

One big difference - array's have sequentialized indexes.
This allows them to be stepped through using a For..Next loop.
Nice.
Collections,though, in .Net are just amorphous groups of "things" (could be any Type of data).
They have no inherent sequencing or ordering.

You'll notice that one of the few methods that the IEnumerator has is the IEnumerator.MoveNext Method.

However, if you are moving something that is ordered into something that is unordered and expect to be able to cleanly reverse the process, there may be issues.

The biggest issue for me (fighting/battling/wrestling with the .Net IDE as always) is that the .Net IDE "knows" about arrays.
It knows what to do with them.
It offers suggestions on how correct errors with them (always wrong suggestions to create/generate
thoroughly unhelpful "stubs" or one type or another..but that's besides the point).

IEnumerators, though, are considered by the VB.Net IDE to be "objects".
What's an object?
If you don't know then the IDE certainly doesn't know!

So I get all kinds of errors like "Object not set" and "object not defined"
and general errors along the lines of:
cannot convert data type to object.

The VS.Net IDE has no helpful error corrections, no autocomplete, poor Intellisense. and almost no helpful MSDN references to give when it encounters an IEnumerator interface used in a way it doesn't understand.

But there are thousands of examples of how to use IEnumerator with VB.Net, right?

Wrong.

So I'll give the one code link I found most helpful:

http://en.wikibooks.org/wiki/Visual_Basic_.NET/Arrays

..which had this helpful code snippet( under "Display all the elements in the array"):
Quote:
Dim MyArray As System.Array
Dim En As System.Collections.IEnumerator
MyArray = System.Array.CreateInstance(GetType(String), 4)
'
MyArray(0) = "a"
MyArray(1) = "d"
MyArray(2) = "b"
MyArray(3) = "c"
En = MyArray.GetEnumerator
These links were also helpful for "background information" on IEnumerators:
http://www.java2s.com/Tutorial/VB/01...Enumerator.htm
http://www.dotnetperls.com/ienumerable-vbnet
http://www.java2s.com/Code/VB/Data-S...likeaccess.htm

I wasn't in the clear yet.
The .3DS loader was defining arrays like this:
Quote:
Dim str3DObjectsNameStringArray As String() = New String(Import3DSObject.SubObjectArray.Count) {}
See those curly braces/brackets at the end.
If you are seeing this in VB.Net code (versus C# code), it's time to sit up and pay attention.

Of course there is more than one way to declare a string array in VB.Net
(using curly braces just happens to be one of the "ugliest" from the point of view of the "natural language" way of expressing things that VB uses [IMHO]).

So (as it turns out) the IEnumerator didn't like the .3DS loaders way of defining arrays,
so I had to use the dim as System.Array way of declaring the array.

Of course there is a "gotcha" in using System.Array (did you catch it?)
It's that the CreateInstance call has not one, but two parameters.
The second one being the size of array.

I couldn't hard code this with a magic number since it's dependent on how complicated the model is in the .3DS file being loaded.
So I actually had figure out how to get the size of the array.
It turns out it's ".Length" not the usual ".Count".


However then I also ran into the classic scoping issue - there really is no way to declare a variable as "globally" scoped in .Net.

You can do Public, Public Shared, Friend, etc. --but none of these is equivalent to throwing a declare publicly in a .bas module under VB6 and be able to access it anywhere with using a class qualifier (i.e. someclass.variable) .

So I ended up re-scoping the .3DS data array into the IniFile class.

Just to debug this I had to depart from using my usual picDebug or MsgBox way for sanity checking what's going on with the array data
to (instead) using a custom form, initialized at runtime, with a scrollable textbox inside.

The 3DS loader interface is pretty crowded already so I didn't want to dump any more scrollable listboxes/textboxes into it just for debugging.

What don't I just set a breakpoint and look at the array data that way?

Some of the arrays I was using for testing had over 10,000 array nodes!
Have you every tried to do a mouseover viewing of such an array at a breakpoint in .Net.
Not fun!
(what --you don't want to click on the variable mouseover floating plus sign 10,000 times to drill down and look at all the array strings..nah, I think I'll skip that..)

Then there where the hassles of dealing with the System.IO.StreamWriter.
I won't even get into that (this post already has enough yawn-inducing coding trivia).

So what's the bottom line (after 4 days and over 20 hours of "playing around")?

The new updated (semi-working) .3DS file to ini file convertor is attached below.

Note: There are some .3DS sample files included in the zip I converted from other 3D forms (to use for testing)

Most should work but don't try "LeonardoVehicle.3ds" using the convertor code.
You'll see what happens if you do - eventually (after almost 2 minutes) it will give you a ContextSwitchDeadlock error (see screenshot below).

I can just image boops boops and passel get these all the time, but it's a first for me!


The VB.Net's IDE's proposed solution:
Quote:
To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
Instead, my recommended "bypass" is to use the original "Complex_3D_WireFrame_Viewer.zip" attached to this post or the "slight revision" update attached below.

I'll attach "screenshot-LeonardoVehicle_3DS_model_rendered as wireframe_with_45670_triangles .JPG" below just so you can see what it looks like.

Note: This model pushes the 3DS loader code to the limit (and can take up to a minute to finally come up rendered on screen).

The largest 3DS model the 3D_to_ini_file_convertor code can load is the astronaut.3ds model (at about 11,000 triangles)..again taking up to a minute (but I put in a "please wait.." textbox that appear while it is loading).

Maybe I should have said: "Your patience is appreciated..."

It would sure be nice to optimize this (maybe using a "parallel for" call or some other ways -if anyone has any suggestions).



I say "semi-working" because it's only saving the basic list of 3D objects as ini file Sections at this point.

More work needs to be done to get it to save the Point3Ds (Vertices) and 3D faces (which it calls "Triangles").

I've got a design decision in this in that I could save the 3D points and vertices as a single keys (comma delimited), or do it "longhand-ed" instead,
by saving one data point for each key/value pair.

The later makes more since (from a point of view of considering the ini file as a "hash table") , but will probably be more work.

Even after all this is done saving to an ini file is only step one though!


Future Roadmap/ToDo list:

Then (step 2) you have to figure out to read back the ini file data from/thru an IEnumerator object/interface to an array that the 3ds loader understands (and can be used to render a wireframe graphic).

Then (step 3) I have to "translate" the 3DS loader's way of rendering graphics into boops boops way of doing things in the Perspective Scene codebase.

Whew!

It's at this point I wish I had a whole team of programmers working for me.
But such is not to be..
It's most likely just going to be a long hard slog through all this "refactoring" (which includes a fair bit of code creation).

Oh..final note..what should the 3 letter file format extension be for this new unique variant on the ini file?
I was thinking (maybe): ".i3n"

I know it would be better (preferable) if I could just stick with one of the standard 3D file formats,
but I'm not making any promises unless someone comes up with some pre-existing VB.Net code to read/write those formats
and render them in 3D (without using OpenGL/DirectX/XNA/WPF).

Last edited by dotnetwrassler; 03-16-2015 at 10:02 AM.
Reply With Quote
  #51  
Old 03-16-2015, 12:02 PM
PlausiblyDamp's Avatar
PlausiblyDampExploring 3D graphics with VB.Net, but without using DirectX or XNA PlausiblyDamp is offline
Ultimate Contributor

Forum Leader
* Expert *
 
Join Date: Nov 2003
Location: Newport, Wales
Posts: 2,052
Default

Out of interest you normally don't need to work with the IEnumerable / IEnumerator directly, the For Each syntax VB provides is a compiler provided way of dealing with these things.

Also looking at your code I noticed an awful lot of array usage and even an ArrayList or two in there, ave you considered using generic lists instead? They can give you a more type safe way of working and also remove the need for the Redim when working with arrays.

I have just done a fairly quick refactor of the project (3d stuff isn't my domain so I didn't understand an awful lot of it) to convert some parts to use generic lists.

Looking further at the code you might be able to simplify a lot more - the IniFile class looks like it is a list of named sections, if so using a Dictionary(of String, Section) would be easier and you wouldn't need to be looping over the sections manually - you could simply return them by name.

The SubObject3D class might be better if the last two properties where
Code:
	Public VertexArray As List(Of Vertex)
	Public TriangleArray As List(Of Triangle)
as this again would be more strongly typed. Although this would probably need further changes to the rest of the code. Not being exactly sure of how they are being used prevented me doing a quick fix. If you like I am happy to see if I can make further changes to remove the need for the IEnumerable and increase the use of generic types.

Edit:
I was bored so I went through the code and updated it to use mainly the generic List(Of ...) type and replaced a lot of the IEnumerable support with For Each loops instead. Seems to work the same as the original but not really tested it. Hopefully will give you an idea of the easier approach.
Attached Files
File Type: zip modified.zip (1.22 MB, 21 views)
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags

Last edited by PlausiblyDamp; 03-16-2015 at 02:52 PM. Reason: Further reading of the code and updating my comments
Reply With Quote
  #52  
Old 03-16-2015, 03:21 PM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

Quote:
Originally Posted by dotnetwrassler View Post
So the cube "bug" is due to an uncorrectly handled Y rotation?
That leaves me I'm wondering what kind tweak would be need to fix this?
No, it's the way multiple rotations combine that's the problem. It may turn out to be simple to fix, but I won't bank on it. The 3DScene code has its "world" coordinates locked to the "device" coordinates: X and Y are always screen X and Y. It makes several things easier, but it may turn out to be a limitation.

Quote:
I already have some preliminary vertices/Point3Ds and face mapping for some other 3D primitives like:
- A Cone
- A Torus
- A Cylinder

The "awkwardness" of the Sphere demo is that is not adhering to the way the Perspective Scene is set up at all.

It basically needs a major re-factoring before it can be merged with the existing BBDP (boops boops, dotnetwrassler, passel) codebase (as you'll see when you take a look at it).
I personally think it was intended to be used/integrated with the use of 3D meshes rather than the way Perspective Scene works up to this point.
The sphere geometry isn't hard as 3D geometry goes, so it should be possible to work something out from scratch. Some day....

Quote:
An EditablePoint3D class would be highly desirable if you can find the time to recreate it.
I can just imagine the many goodies stashed away (unpublished) on the boops boops hard drive(s).
Would you kindly refrain from posting your imaginings here. Besides, it would take a large team of pig farmers to muck out my hard drive.

Quote:
Here's one "feature" I thought of, which I have no idea to implement (but would be desirable).

Right now we can detect whether the mouse is over (and ready to drag) a full solid or just a point.

Great.

But what about an "edge detection" routine that would trigger a boolean if the mouse is over a line between the faces.

One could then use that boolean to:
1.) drag the line (with the two vertices at either end in tow) OR
2.) possibly insert a 3D point in a mouse down event (maybe right click mouse down) that could do a triangulation bisection along that edge that would split the face.

Pretty crazy idea, huh?
Not at all, since the Edge3Ds are defined for each solid. Detecting a hover or click on an edge is not too different from a Point3d; they are both actually a 2D affair. It shouldn't be hard to add a demo to the PerspectiveScene, but don't expect too much of it. It would take a lot more development to do anything more than distort the solids into rather arbitrary shapes.
Quote:
Re: Design time file loading and saving

I am working with every spare moment I can get to merge the .3DS model file loading code into the BBDP code base.

I consider it absolutely necessary to add reading/writing to disk for design-time "persistence" if the project is to have any chance of being truly useful in a general way to non-programmers (where everything isn't hard-coded at runtime).

However, I really do not care if the file format is the .3ds (a 3D Studio Max) format,
or some other type of standard format (like Collada/SketchupPro's DAE, AutoCad's dxf/dwg (which I'm sure Gruff would like), Blenders ever-morphing .blend format,
or some custom format).

I went with .3DS straightaway because (of course) a working attachment of VB.Net code for loading and display of such files already exists (has been published) on this forum.

Anyone who has some thoughts on this, please feel free to post suggestions.
For the 3DScene program, it should only take a dozen or so lines of Serialization code to save and load scenes. Wouldn't that be sufficient for the while?

Quote:
Just thinking about this gives me the heebie jeebies though...scaling factors, camera orientations, lighting/shader effects support (including Blender Cycle-style "bounce lighting"), UV wrapping, bones/forward/inverse kinetics, caustics, Maya-type soft body dynamic constraint attributes (including emitted particle springs), inter-mesh intersection booleans, model nesting, multi-layer and multiple "scene" support support, animation timelining, etc..

--and that list doesn't even include real world physic modelling.

Yes, it can be a huge "swamp" of expectations to wade into.
Consider all that stuff off topic for this thread. It's not that they can't be done in GDI+ (in theory at least) but you won't find the knowledge you need in GDI+ terms. You would end up having to reinvent everything for yourself. As far as I am concerned, the point of considering what can be done without DirectX, XNA etc. is getting a simple introduction to 3d. That's all.

I'll make one exception though: it would be interesting to introduce some simple shading into the 3DScene. At the moment, the program uses transparent colors as a way of depicting depth in a solid. It works well enough for polygons, but it won't be as good for a sphere.
Quote:
So to anyone who is following this thread (without posting) please know the initial "saveTo" and "readFrom" file code will be very humble.

Maybe even something as basic as using the forum's posted working VB.Net .ini file "sampler" code.
I'll see if I can add Serialization once I can find some time to play with the code again. Not ini files please -- they went out of fashion with Win95!

p.s. I agree with PlausiblyDamp. Untyped Arrays and ArrayLists are only required for backward compatibility. If you find code using it on the web, consider it out of date. The Generic collections -- especially List(Of T) and Dictionary(Of T) -- introduced in VB2005 are vastly more efficient and reliable.

BB
Reply With Quote
  #53  
Old 03-20-2015, 10:40 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default A team of pig farmers..and setting the agenda going forward..

Quote:
Originally Posted by boops boops
The 3DScene code has its "world" coordinates locked to the "device" coordinates: X and Y are always screen X and Y. It makes several things easier, but it may turn out to be a limitation.
Yes, playing around with the x,y coordinates I realized that "lock" but I was hoping there was a workaround.

I guess that gives higher priority to eventually working the quaternion code into the Perspective Scene codebase.

Quote:
Originally Posted by boops boops
Detecting a hover or click on an edge is not too different from a Point3d; they are both actually a 2D affair. It shouldn't be hard to add a demo to the PerspectiveScene, but don't expect too much of it. It would take a lot more development to do anything more than distort the solids into rather arbitrary shapes.
Anything that moves the project from just being a demo (with basically "pre-rolled" graphics) to being able to manipulate the 3D objects more at runtime is desirable at this point.

Quote:
Originally Posted by boops boops
For the 3DScene program, it should only take a dozen or so lines of Serialization code to save and load scenes. Wouldn't that be sufficient for the while?
Yes!

Quote:
Originally Posted by boops boops
I'll see if I can add Serialization once I can find some time to play with the code again.
Looking forward to it.

But for right now the only "bridge" I have between the .3DS file loading code and the bbdp code base is through ini files.

I know ini files are old school (but then so am I).

I understand them (even if I don't understand the IEnumerator VB.Net implementation of how to use them for File I/O reading/writing).
I want to understand better how Collections work --which I guess touches on Generic collections -- especially List(Of T) and Dictionary(Of T).

Part of this project is definitely for me to learn the ".Net way" of doing things, but you have to crawl before you can walk (or run).

I'll consider the use of ini files a personal "side branch" separate from the main "trunk" code being developed in this thread, though.

'*************************

Here's a little side note of something I thought about (but dismissed)

The other .Net way of doing things is to use .xml files.

There are a number of "downsides" that make me reluctant to go in that direction:
1.) Besides there not being a single "standard" 3D file format, there is also no "standard" for using xml with 3D graphics.

Dassault Systemes' 3DXML file format competes with X3D and AutoCad's XML implementation (there are probably others as well)

2.) XML nesting --it's potentially close to infinite!
Theoretically you could nest things a million levels deep!
What would that do for the performance of an xml parser - not good things I suspect.
What if you had to find (and substitute/inject//adjust) the text of multiple branches within that million level deep hierarchy.
It's a nightmare even to thing about.

3.) The biggest thing though - except for the Tree control there is basically no .Net control that is designed to graphically display deeply nested xml.

The Tree control displays it badly - not enough consideration was given to "smart collapsing" including "mouseover-based uncollapse browsing" (using twisty triangles).

Dragging/dropping, changing "view" types, altering color/text theming, data binding options --there is just so much that is missing for the "basic" Tree control that comes bundled with .Net.

Graphically...well..the tree control barely even supports node icons --what if I wanted to substitute runtime generated graphics (like UV wrapping textures) for some of the xml text branches.

Yes it has the "e.graphics" of every .Net control but other than that it wasn't designed for such runtime graphics.

If only Microsoft had spent just a little bit more effort into designing a more advanced .Net Tree control like this one.

Anyway..moving on (past xml)..

'********************************

Quote:
Originally Posted by boops boops
I'll make one exception though: it would be interesting to introduce some simple shading into the 3DScene.
Yes it would.

With your expertise in VB.Net graphics I'm sure you could come up with some interesting "faux" shading...even if it's just using .Net gradient functions..

However, working with alpha blending using color matrices (at the per pixel level) you realize how tantalizing the possibilities/potentialities and yet how tedious the implementation.

I guess it beats trying to do some kind of ray tracing, or work with voxels, though.


Overall it sounds like we're on the same page.

If only each of us can find the time to keep pressing things forward.
There is just so much to do!

That hypothetical team of pig farmers would sure come in handy right now if they could do a little coding for us.

Last edited by dotnetwrassler; 03-20-2015 at 11:18 AM.
Reply With Quote
  #54  
Old 03-20-2015, 04:04 PM
passel's Avatar
passelExploring 3D graphics with VB.Net, but without using DirectX or XNA passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,011
Default

I've been busy, so not going to be participating really, but I do check in occasionally. I somehow missed your post just before PlausiblyDamp's and his, but "discovered" them today when looking back. Although I won't be providing much to the conversation, a couple of responses to your older post.
Quote:
Originally Posted by dotnetwrassler View Post
...then I also ran into the classic scoping issue - there really is no way to declare a variable as "globally" scoped in .Net.

You can do Public, Public Shared, Friend, etc. --but none of these is equivalent to throwing a declare publicly in a .bas module under VB6 and be able to access it anywhere with using a class qualifier (i.e. someclass.variable) .
...
You can still declare a public variable in a Module in VB.Net and it will have global scope. Of course some people don't like that namespace "pollution", having the ability to see a variable everywhere without being required to qualify it.
You also have the option of creating a Class module, declaring the elements as Public Shared, so they can be accessed anywhere by "someclass.variable" without having to instantiate the class, (example Math.PI).
Examples of using Modules vs Classes with Shared elements vs Classes that has to be instantiated, was done in post #12 of this thread, which you should remember well (the thread, if not the specifics of the code implementation).
Quote:
Originally Posted by dotnetwrassler View Post
... but don't try "LeonardoVehicle.3ds" using the convertor code.
You'll see what happens if you do - eventually (after almost 2 minutes) it will give you a ContextSwitchDeadlock error (see screenshot below).

I can just image boops boops and passel get these all the time, but it's a first for me!
...
No, I don't recall ever getting a ContextSwitchDeadlock error before.
I don't usually deal with really large amounts of data. I prefer running VB.Net in x86 mode as you can make changes in the IDE while running and the graphics (GDI+ based) code actually seems to run a little faster than compiling into an x64 executable.
But, I did have to choose x64 lately when I was trying to play around with a 750MB geotiff file. VB in 32-bit mode would run out of memory trying to open the file, so 64-bit was the only choice to get the full image data into memory for display.
If you could make source code changes while stepping through the code in x64-bit mode, I would probably use it by default, although the GDI+ code being quicker in 32-bit mode might still be reason enough not to use 64-bit when not needed.

p.s. I took a quick look at the "3DS_File_Loader_slight_revision.zip" and saw what it was doing in the ReadDouble() and other functions. I could see it was just changing a run of bytes into a numeric type, and I do that kind of thing regularly in my job, using routines .Net provides that will do that. I modified the ReadDouble function as a quick test and it worked fine, with a lot less code. All the ReadDouble is doing is converting four bytes from the file into a Single and returning it in a double.
So, this function
Code:
  Public Function ReadDouble() As Double
    Dim bits As Integer
    Dim sign As Integer
    Dim exponent As Integer
    Dim mantissa As Integer
    Dim result As Double
    bits = ReadInt()
    If ((bits And 2147483648) = 0) Then
      sign = 1
    Else
      sign = -1
    End If
    exponent = ((bits And 2139095040) >> 23)
    mantissa = (bits And 8388607)
    mantissa = mantissa Or 8388608
    result = sign * mantissa * Math.Pow(2, exponent - 150)
    Return result
  End Function
Can be changed to
Code:
  Public Function ReadDouble() As Double
    'Read a Single from the byte array and return as a Double
    CurrentIndex += 4 'pre-increment to skip over the bytes we will be processing
    Return BitConverter.ToSingle(ByteArray, CurrentIndex - 3) 'and convert the four bytes to a Single
  End Function
This avoids the call to ReadInt, and the four calls ReadInt does to ReadByte, plus the math to shift and calculate the floating point parts manually.

But, when rerunning the code, it didn't really make any perceptible difference in time since it is just math and the byte array is decoded really quickly.
On my machine it took about 10 seconds for the LeonardoVehicle.3ds file to display, but the reading into the byte array and parsing the byte array was only a fraction of a second.

So, I looked to see where the majority of the 10 seconds was being spent.
The answer was the filling of the two ListBoxes in the FillListBox sub of the main form.
I knew of a quicker way to fill a listbox, so I changed that sub and now the LeonardoVehicle.3ds file is displayed within 2 seconds after it is selected.
The speed up is to not add items to the listbox individually, but to add the strings to a List(Of String) object, then use the .AddRange method and the List.ToArray method to add the whole array of strings to the Listbox in one shot.
Code:
  Public Sub FillListBox()
    Dim tList As New List(Of String) 'Collect our list here, then add the list to the Listbox in one call

    ListBox_Triangle.Items.Clear()
    ListBox_Vertex.Items.Clear()
    SubObjectObj = Import3DSObject.SubObjectArray.Item(ComboBox_SubObjects.SelectedIndex)
    Label_TotalVertices.Text = "Total Vertices: " & SubObjectObj.VertexArray.Count
    Label_TotalTriangles.Text = "Total Triangles: " & SubObjectObj.TriangleArray.Count
    For j = 0 To SubObjectObj.VertexArray.Count - 1 Step 1
      VertexObj = SubObjectObj.VertexArray.Item(j)
      tList.Add("V" & j & ": (" & Format(VertexObj.X, "##,##0.00") & _
         ", " & Format(VertexObj.X, "##,##0.00") & ", " & Format(VertexObj.X, "##,##0.00") & ")")
      'ListBox_Vertex.Items.Add("V" & j & ": (" & Format(VertexObj.X, "##,##0.00") & _
      '   ", " & Format(VertexObj.X, "##,##0.00") & ", " & Format(VertexObj.X, "##,##0.00") & ")")
    Next
    ListBox_Vertex.Items.AddRange(tList.ToArray)   'Add the array in one shot to the listbox
    ListBox_Vertex.SelectedIndex = 0

    tList.Clear()
    For j = 0 To SubObjectObj.TriangleArray.Count - 1 Step 1
      TriangleObj = SubObjectObj.TriangleArray.Item(j)
      tList.Add("T" & (j + 1) & ": (" & TriangleObj.V1 & ", " & _
        TriangleObj.V2 & ", " & TriangleObj.V3 & ")")
    Next
    ListBox_Triangle.Items.AddRange(tList.ToArray)   'add all the strings in one shot
    ListBox_Triangle.SelectedIndex = 0
  End Sub
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 03-20-2015 at 06:01 PM.
Reply With Quote
  #55  
Old 03-20-2015, 07:16 PM
passel's Avatar
passelExploring 3D graphics with VB.Net, but without using DirectX or XNA passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,011
Default

I also looked at your newer .ini file creator and PlausiblyDamp's version (briefly).
I tried loading the LeonardoVehicle.3ds and saw the same error when the code hung up the GUI thread for more than 60 seconds.
I looked at the FillListBox sub again to see what has changed and you are building two hugh strings MessageString2 and MessageString3 by using concatenation.
Concatenation is only to be used with short strings. If you need to build strings more than a few hundred characters you should be using a StringBuilder object.
MessageString2 is taking more than 60 seconds to build all by itself, so that it why Windows gives up on a non-responsive window.
Using a StringBuilder object to build the string it takes a little over 1/10th of a second to build the string that concatenation couldn't finish in 60 seconds.
So the version below is the one from PlausiblyDamp's post, with the List(Of String) and the StringBuilder changes, and it does the Leonardo file in a couple of seconds. I didn't know why the StringBuilder.Clear() method was missing, but then realized it is a framework 4.0 or above method. Is there a reason you're targeting the 2.0 framework?
Code:
  Public Sub FillListBox()
    Dim tList As New List(Of String) 'Collect our list here, then add the list to the Listbox in one call

    'Dim str3DObjectsNameStringArray As String() = New String(Import3DSObject.SubObjectArray.Count) {}

    'Dim MyArray As System.Array
    '	IniFile.MyArray = System.Array.CreateInstance(GetType(String), (Import3DSObject.SubObjectArray.Count))
    Dim sb As New System.Text.StringBuilder

    Dim str3DObjectsVerticesListArray As New List(Of String)
    Dim str3DObjectsTrianglesListArray As New List(Of String)
    ListBox_Triangle.Items.Clear()
    ListBox_Vertex.Items.Clear()
    SubObjectObj = Import3DSObject.SubObjectArray.Item(ComboBox_SubObjects.SelectedIndex)
    For j = 0 To Import3DSObject.SubObjectArray.Count - 1 Step 1

      IniFile.str3DObjectsNameStringArray.Add(Import3DSObject.SubObjectArray.Item(j).SubObjectName)
      IniFile.MyArray.Add(Import3DSObject.SubObjectArray.Item(j).SubObjectName)
      'MessageString = MessageString & IniFile._str3DObjectsNameStringArray(j) & Environment.NewLine
    Next

    Label_TotalVertices.Text = "Total Vertices: " & SubObjectObj.VertexArray.Count
    Label_TotalTriangles.Text = "Total Triangles: " & SubObjectObj.TriangleArray.Count
    For j = 0 To SubObjectObj.VertexArray.Count - 1 Step 1
      VertexObj = SubObjectObj.VertexArray.Item(j)
      sb.AppendLine("Vertex" & j & "---" & _
                  "X:" & VertexObj.X & ", " & _
                  "Y:" & VertexObj.Y & ", " & _
                  "Z:" & VertexObj.Z)

      tList.Add("V" & j & ": (" & Format(VertexObj.X, "##,##0.00") & _
         ", " & Format(VertexObj.X, "##,##0.00") & ", " & Format(VertexObj.X, "##,##0.00") & ")")
    Next
    MessageString2 = sb.ToString
    ListBox_Vertex.Items.AddRange(tList.ToArray)

    txtPOP1.Visible = False 'turn off "populating.." textbox message
    ListBox_Vertex.Refresh()
    Application.DoEvents()

    tList.Clear()
    sb = New StringBuilder        'sb.Clear() method not available on my machine today? Oh, we're targeting the 2.0 framework, why?
    ListBox_Vertex.SelectedIndex = 0
    For j = 0 To SubObjectObj.TriangleArray.Count - 1 Step 1
      TriangleObj = SubObjectObj.TriangleArray.Item(j)
      tList.Add("T" & (j + 1) & ": (" & TriangleObj.V1 & ", " & _
        TriangleObj.V2 & ", " & TriangleObj.V3 & ")")

      sb.AppendLine("Triangle" & j & "---" & _
                "VertexUsed #1: " & TriangleObj.V1 & " , " & _
                " VertexUsed #2: " & TriangleObj.V2 & " , " & _
                " VertexUsed #3: " & TriangleObj.V3)
    Next
    MessageString3 = sb.ToString
    ListBox_Triangle.Items.AddRange(tList.ToArray)

    txtPop2.Visible = False 'turn off "populating.." textbox message
    ListBox_Triangle.SelectedIndex = 0
  End Sub
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #56  
Old 03-21-2015, 07:04 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Stringbuilding..including StringBuilder.Clear and Stringbuilder.Remove

Thanks for the double posting, passel!
I've really missed your contributions (and valuable code optimizations) for the code in this thread.

I know my last code attachment was a bit of a mess.

Thanks for taking the time to look at it though (and helping out with some optimized snippets).

The snippets are definitely timely because I'm still trying to "flesh out" a proper debugging for the merger of the .3DS loader and BBDP ("Perspective_Scene") codebases.

Quote:
Originally Posted by passel
Examples of using Modules vs Classes with Shared elements vs Classes that has to be instantiated, was done in post #12 of this thread, which you should remember well (the thread, if not the specifics of the code implementation).
Of course I remember your QuickInvaders example thread, but it's always those "specifics of the code implementation" that makes it hard for me to churn out code as optimized as yours.

Quote:
Originally Posted by passel
If you could make source code changes while stepping through the code in x64-bit mode, I would probably use it by default, although the GDI+ code being quicker in 32-bit mode might still be reason enough not to use 64-bit when not needed.
I'm still getting used to not being able to make changes while debugging, stopped at a breakpoint.

Yes, 32 bit is faster, but the future (going forward) is all about 64 bit.
I have to get used to that.

This was one of the few viable reasons for moving from VB6 to VB.Net that I would say was "justifiable"
(although I don't really understand why VB6 couldn't have been converted over to 64 bit..even though
it would have probably been a major rewrite it was not totally technically impossible).

Maybe someday Microsoft will embrace something like 128 bit ZFS (Zettabyte File System) and
manipulating data loaded from exabyte file storage will be fully able to take advantage of a 64 bit O/S.

Apple already embraced replacing the old HFS+ with ZFS a few years ago:
http://www.macworld.com/article/1058289/sun.html


Quote:
Originally Posted by passel
Is there a reason you're targeting the 2.0 framework?
The 3DS loader code is that old.

At this point I didn't see any reason to switch framework versions.

In the past when I've switched framework versions for projects it usually ends up necessitating
extra code refactoring (if for no other reason then to take advantage of extra functions/methods).

I did a few ASP.Net projects and the difference in coding between using 3.5 and 4.0 was like night and day.



Right now, though, there is already a fair bit of refactoring going on with just trying to "fold" the
ini file writing (saving) code in with the .3DS file opening/reading/displaying code.

However in the other examples I've seen of using StringBuilder with the 2.0 Framework, the tendency has been
to use (in place of the new StringBuilder.Clear) the StringBuilder.Remove method (available all the way back to the 1.1 Framework, I believe):
http://bobondevelopment.com/2007/06/...omment-page-1/

As the above article notes, unlike String.Length, the StringBuilder.Length is not readonly!

Don't believe me?

Here is the MSDN page for StringBuilder.Length "property":
https://msdn.microsoft.com/en-us/lib...or=-2147217396

..where it clear states (under "Remarks"):
Quote:
Like the String.Length property, the Length property indicates the length of the current string object.

Unlike the String.Length property, which is read-only, the Length property allows you to modify the length of the string stored to the StringBuilder object.

If the specified length is less than the current length, the current StringBuilder object is truncated to the specified length. If the specified length is greater than the current length, the end of the string value of the current StringBuilder object is padded with the Unicode NULL character (U+0000).

If the specified length is greater than the current capacity, Capacity increases so that it is greater than or equal to the specified length.
I put "property" in quotes because anything that is used in changing something "mutable" (not readonly) at runtime
I tend to think of as a method instead of a property.



To PlausiblyDamp,

I didn't ignore you when you posted earlier, but I wanted to try and understand your attachment before posting..

Definitely thanks for trying to help out even though:
Quote:
Originally Posted by PlausiblyDamp
..3d stuff isn't my domain..
The new way of coding 3D objects in VB.Net that this thread represents (by extending GDI+ to essentially what amounts to a System.Drawing.Drawing3D Namespace)
is entirely new and there is no "expert" in what we are trying to do, so we are all trying to "feel our way" forward,
and I continue to welcome your additions to the thread.

Quote:
Originally Posted by PlausiblyDamp
You normally don't need to work with the IEnumerable / IEnumerator directly, the For Each syntax VB provides is a compiler provided way of dealing with these things..
I frankly admit to not having worked much with IEnumerator so this news to me.

If IEnumerator works with For Each does that mean it can also work with the Parallel.For method?

Quote:
I went through the code and updated it to use mainly the generic List(Of ...) type and replaced a lot of the IEnumerable support with For Each loops instead. Seems to work the same as the original but not really tested it. Hopefully will give you an idea of the easier approach..
Oh no (), more code merging/refactoring ahead!

I will spend some time studying the "modified.zip" code and see if I can wrap my head around it.

I'm sure it's an "easier approach" for you because you are:
1.) Used to working with such "newfangled" Generic List(Of ...) collections (my head still has some old VB6 "cobwebs" to clear out)
2.) One of the forum's premier Leaders/ Experts

I don't make any guarantees though..there is a lot of old array code tied in with the 3D rendering that will have to be looked at
when it comes time to "sync" it with the BBDP way of representing Point3Ds and Faces, but it's nice to have extra options.

Don't expect another code update for at least a week (my work schedule is crazy for the next 6 days) but
rest assured I will keep pounding away at the code until I find a way to save out all the vertices and triangles to a file.

Maybe this will give boops boops time to add edge dragging to Perspective Scene.

Last edited by dotnetwrassler; 03-21-2015 at 08:01 AM.
Reply With Quote
  #57  
Old 03-21-2015, 08:48 AM
PlausiblyDamp's Avatar
PlausiblyDampExploring 3D graphics with VB.Net, but without using DirectX or XNA PlausiblyDamp is offline
Ultimate Contributor

Forum Leader
* Expert *
 
Join Date: Nov 2003
Location: Newport, Wales
Posts: 2,052
Default

Hi,

A lot of the issues you were having with IEnumerable date to pre .Net 2.0 days - the IEnumerable / IEnumerator interfaces only dealt with object, this is why you had no intellisense or compiler help.

The generic versions included with .Net and later allow you to use strongly typed versions of these which give a much better development experience.

Once you get used to things like List(Of ...) it is very similar to an ArrayList but with proper strongly typed code. The other advantage is not having to manually control the size like an array requires.

You should be able to use the Parallel.For in the same way you use a normal For ... Next loop. If you look at the Parallel.ForEach thoughthat should work with IEnumerable, preferably a generic version though for the better compiler / IDE support.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #58  
Old 03-23-2015, 06:22 AM
passel's Avatar
passelExploring 3D graphics with VB.Net, but without using DirectX or XNA passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,011
Default

Quote:
Originally Posted by dotnetwrassler View Post
...
At this point I didn't see any reason to switch framework versions.
...
If IEnumerator works with For Each does that mean it can also work with the Parallel.For method?...
Of course the Parallel.For was introduced in Net 4.0, so if you're sticking with 2.0, no need to consider Parallel.For
Quote:
Originally Posted by dotnetwrassler View Post
...
In the past when I've switched framework versions for projects it usually ends up necessitating
extra code refactoring (if for no other reason then to take advantage of extra functions/methods).
By the way, I changed the Target Framework to 4.0 under the Advanced Compiler Settings, and didn't have to change any code at all. It ran fine as is.

Also, since the IDE supports generating both 32-bit and 64-bit exes easily, I'll continue to work in 32-bit in the IDE for productivity, and generate 64-bit exes for use, if necessary. The exception, or course, will be if I can't work in the 32-bit address space, then I'll have no choice but use 64-bit in the IDE and revert to more traditional debugging methods (designing in debug so enabling or disabling flags, or changing variables in the immediate window will affect the flow of the code, etc. without changing code).
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 03-23-2015 at 06:31 AM.
Reply With Quote
  #59  
Old 03-23-2015, 04:35 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Merging/converting code issues..and new version

Thanks for the extra info, passel and PlausiblyDamp (including validating the possibility of using Parallel For).

I tried to merge the revised IniFile class code (from PD's modified.zip attachment to post 51) with
passel's code revision for the FillListBox sub and ReadDouble function (from post 54).

There were some issues.

The new FillListBox sub code (on the MainForm) didn't have Clear() and a For..Next loop for the Listbox items/data connected with SubObjectObj.

Maybe it wasn't obvious...but .3ds files have separate names (one or more) for the different sub-objects that make up the full 3D model.
It's not just 3D points (vertices) and faces/triangles.

So the sub-object name list also has to have it's own separate String List,
which is used for the Sections part of the .ini file.

Recycling 'tList' for both the vertices and triangles (with a clear in between) isn't going to work,
because I need to retain both and transfer each String List data separately to
create a well-formed key/value combo using the IniFile class' SaveTransfer sub.

I think it will work best if I had three separate String Lists for the next version (which will
be a pre-cursor to eventually finding a way to load the model data into
the PS5 code attached to post 47, with post #48's Oct+Icos.zip revision attachment merged in)***

Also passel's FillListBox code and PD's code weren't "cross-connecting" (passing data between them)
so the SaveTransfer sub of the IniFile class wasn't working at all (zero byte file formed).


***************************************************

Long story short I refactored and re-integrated everything so now it's "back to where it was before" (saving the Sections to an ini file)..except:
1.) The code no longer has to deal directly with IEnumerator calls for the SaveTransfer sub.
2.) The LeonardoVehicle.3ds model is loading/rendering in less than 2 seconds (instead over a minute with a ContextSwitchDeadlock error).

I'll attach the new working version2c below.
I left out most of the .3ds text models from the attachments to post #50 this time (except for the for the LeonardoVehicle model).

I noticed that 3D wireframe LeonardoVehicle model hesitating (stuttering) when trying to render while drag rotating in real time (on my computer),
but maybe there's nothing that can be done about that because of how complex the model is..

***For the next version I still have yet to work out the code for
saving out the vertices and triangles using System.IO.StreamWriter.

I also have (at this point) no non-IEnumerator code for opening and reading the 3DS files
(another "ToDo" item to try and convert it to using String Lists also).

Oh..I just noticed that this thread had over 6300 views ---can all that really be from just the 4 forum members involved, or
could the thread possibly have some interest to others who have not posted as well..hmmm..
Attached Files
File Type: zip 3DS_file_to_Ini_file_converter2c.zip (790.4 KB, 13 views)

Last edited by dotnetwrassler; 03-23-2015 at 05:12 PM.
Reply With Quote
  #60  
Old 03-25-2015, 03:51 AM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Progress writing out Point3Ds (vertices) & triangle faces to file..

Latest revision does write out Point3Ds (vertices) & triangle faces to file,
but just not in the format that would be the most useful.

First there's an indexed list of the model sub-objects (which might come in handy):
Quote:
[ListIndex of Model Sub-Objects]
0=Box20
1=Box17
2=Box15
3=Box14
4=Box12
5=Box10
6=Box08
7=Box07
8=Box05
9=Box03
10=Box01
11=Blob
12=Link3
13=Inside3
14=Link2
15=Inside2
16=Link1
17=Inside1
The above section of keys/values is writing to file properly (all well and good).


However when I write the vertices and triangles,
they are only for those associated with the selected index (top item)
shown in the SubObjects combobox control.

When it first loads that selected index item happens to be: "Box 20".


What I need is for the .ini file to list all the vertices and triangles used, but
separately for each model sub-object like:

Quote:
[Box 20 model sub-object]
key/value list of Box 20 model sub-object vertices
key/value list of Box 20 model sub-object triangles

[Box 17 model sub-object]
key/value list of Box 17 model sub-object vertices
key/value list of Box 17 model sub-object triangles

[Box 15 model sub-object]
key/value list of Box 15 model sub-object vertices
key/value list of Box 15 model sub-object triangles

etc.
With complete sections/keys/values for all 17 of the model sub-objects (and their associated vertices and triangles)


I think I have to use the 'SubObjectObj' assigned by this line near the top of the FillListBox sub of the MainForm:

Code:
'add list of model sub-objects to dropdown list
SubObjectObj = Import3DSObject.SubObjectArray.Item(ComboBox_SubObjects.SelectedIndex)

However the StreamWriter save-to-file routine code (in the SaveTransfer sub of the IniFile class) also has to be adjusted --additionally nested somehow?


Here's the way it looks now (working, but not nested/nesting properly):

Quote:
Public Sub SaveTransfer(ByVal FileName As String)
Dim i As Integer = 0 'used as count variable
' Remove the existing file
If File.Exists(FileName) Then File.Delete(FileName)
'Loop through the arraylist (Content) and write each line to the file
Dim sw As New System.IO.StreamWriter(FileName)
sw.Write(vbCrLf) 'include spacing line feed
'write section title for index list of model subobject(s)
sw.Write(AddBrackets("ListIndex of Model Sub-Objects") & vbCrLf)
'write names of model subobject(s)
For Each item As String In str3DObjectsNameStringArray
sw.Write(i & "=" & item & vbCrLf)
i = i + 1
Next
i = 1 'reset count variable
sw.Write(vbCrLf) 'include spacing line feed
'write vertices (3D points)
For Each item As String In str3DObjectsVertices
sw.Write("V" & i & "=" & item & vbCrLf)
i = i + 1
Next
i = 1 'reset count variable
sw.Write(vbCrLf) 'include spacing line feed
'write triangle faces
For Each item As String In str3DObjectsTriangles
sw.Write("T" & i & "=" & item & vbCrLf)
i = i + 1
Next
sw.Close()
End Sub
I'll keep massaging the code, but I wanted to post a "waypoint" revision (attached below) of where I'm at now..

It has the impreza.3ds model that has at least 4 model sub-objects
(or you can use the "built-in" 'Linkable.3ds' model which
was used to generate the 17 model subobjects listed above).


----------------------------------------------------------------

Trying to figure out how to do this would be much easier if I didn't have to deal with a class that sits outside the form.

For a modularization optimization standpoint maybe I need to create a "SharedData" class
which has all the List type variables declared with Public Shared scoping.

That way such a class could be the "bridge" (focal point) between the IniFile class and the MainForm code.
A single place I could debug everything that is happening with the data instead of having to jump around looking a breakpoints in different tabs.

..or (here's the lazy programmer speaking) maybe just dump all the IniFile class code directly onto the form?

Probably keeping everything separate is better from a code design standpoint but
from a "minimizing scoping tediousness" standpoint I'm tempted to go the other way..
Attached Files
File Type: zip 3DS_file_to_Ini_file_converter2d.zip (330.2 KB, 15 views)

Last edited by dotnetwrassler; 03-25-2015 at 04:00 AM.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
 
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
Exploring 3D graphics with VB.Net, but without using DirectX or XNA
 
-->