Friday, December 23, 2011

Point in Plane (finally)

One of the last things I've been stuck on is figuring out if a point is within a plane in. After playing around with nearestPointInMesh a couple days ago, it seemed that the function was designed to determine if a point was inside a 3-dimensional mesh rather than a 2D plan (though I still consider that a mesh), which let to a few days of frustration and misunderstanding.

I ended up coming across Jeren Chen's code on determining if a point is inside a mesh without using plug-ins (which I really prefer since you shouldn't assume your user has all the plug-ins you do). His code, like the Maya plug-in, functioned on a 3D mesh rather than a 2D plane, but I ended up writing a hacky function that takes in a plane, moves it down the y axis a tiny bit and extrudes it upwards twice that amount to form a "buffer" 3d mesh for that plane. And then I called Jeren's code. For those wondering it looks like this:
def pointInPlane(v, p):
    # convert point to MPoint
    m = MPoint()
    coord = cmds.xform(v, q = True, ws = True, t = True)
    m.x = float(coord[0])
    m.y = float(coord[1])
    m.z = float(coord[2])
   
    # copy the given plane (since we'll be extruding it and deleting afterwards)
    plane = cmds.duplicate(p)
   
    # select all faces on the plane
    cmds.select(plane, r=True)
    cmds.ConvertSelectionToFaces()
    f = cmds.ls(sl=True)

    # move plane down a bit and extrude upwards to form a thin "buffer" mesh for the pointInMesh function
    cmds.move(0, -0.05, 0, plane, a=True)
    e = cmds.polyExtrudeFacet(ty=0.1)
   
    # get the resulting polygon
    poly = getPolyFromFace(f)
   
    # call pointInMesh function
    inside = isInside(m,poly)
   
    # delete the copied poly
    cmds.delete(plane)
   
    return inside

Hacky as it is, it works (yay!)

Thursday, December 22, 2011

Bug Fix + Self Note

I found out that running my code on a computer that wasn't my laptop would result in the trees not being able to load, since in my code I had specified them via an absolute file path. Just fixed that by making a new function that would find the current file path via python's os module, and navigate into the assets folder. Just as a self-reminder, the command to find the path of the script that's running is:

return os.path.abspath( __file__ )

Friday, December 16, 2011

Making the GUI

Most of the GUI has been implemented! Right now the GUI is separated into 3 tabs, with the first one controlling all map-related functions (such as subdivision), the second one controlling all building-generating parameters, and the third one displaying a map of color to asset name (still in progress). As of now I'm able to generate buildings via the GUI.





Thinking about also including a color editor in the GUI so the user doesn't have to navigate to Maya's Color Set Editor to change the faces.

Also, I'm still working on figuring out if a point falls within a plane. Joe suggested I use the closestPointOnSurface command, but that seems to be a plug-in that happens to be missing from my version of Maya, and I can't find a download for it at the moment. I have, however, found a nearestPointOnMesh command in my plug-in directory, so I'll be looking into that tomorrow.

Monday, December 12, 2011

I heard you like faces, so I put a face in your face...

Working on implementing subdivisions right now. One thing I've come to notice is that depending on how the face is generated (ie. via the interactive split tool or cut faces tool), running the same subdivide command can generate different results.

For example, in the instance below, I'm trying to add split each face into 4 sections in the u-direction. Some faces split fine, others aren't affected at all.

Direction-specific splitting. Some faces unchanged.

One solution I've found is to split each face recursively*, rather than in a particular direction. Though this offers slightly less control over how the faces are split, it does manage to affect every face.

*With divisions set to 3 in quad mode, each initial quadrilateral will be recursively subdivided into 4 subfaces 3 times, yielding a total of 4 * 4 * 4 = 64 faces.

Recursive splitting. All faces modified.

While it is possible to implement directional subdivision, it would require the user to refrain from using certain tools in generating the map. Between the two choices, I decided in favor giving the user the more freedom while retaining basic functionality.

Sunday, December 4, 2011

Self Evaluation

It's time for some introspective self-evaluation.

Looking back on my initial proposal, I realized that starting out, my goals weren't very clear. There are two types of procedural generation when creating a city—the generation of the individual building, and the generation of the whole city from many buildings. At first I had planned to tackle both these problems, but combined with a rather steep learning curve for MEL, this proved to be a bit too ambitious. It's fair to say that I underestimated how long it would take to really understand how MEL worked and how to manipulate objects through MEL effectively. After getting feedback from my Alpha Review, I stepped back and reevaluated my project. This led to a change in direction that I feel was ultimately a positive turn for my project. I decided to focus on the generation of a whole city, since it allowed for more artistic experimentation (generating the different building types), as well as a more practical final product.

While my current project is fairly different than what I had originally envisioned, I'm quite happy at how it turned out. Here is a list of features I have today:

  • Ability to generate buildings from either faces or polygons
  • Established framework for adding additional types of buildings
  • Generation of different building types depending on face color
  • 3 different types of assets: residential, business, trees
  • Ability to import additional assets as Maya ASCII files
  • Setting max/min height of generated buildings (currently hard-coded)
  • Setting cell width of building windows (currently hard-coded)
  • Generation of random types of roots/details on buildings

    Please see my previous post for features I'm planning on implementing the next few weeks. Eventually I'm hoping to create a script that's easily extensible so users can have more control over what types of assets are generated (ie. a backyard with different types of plants instead of being limited to a city)

    Beta Review and Future Plans

    I had my Beta Review with Norm and Joe on Friday, and I'd say it went over pretty well. I implemented Norm's suggestion on color-coding building footprints to determine the generated structure type, as well as importing external Maya ASCII files into the library of available assets. Results-wise, I was able to generate a city with multiple building types as well as trees (imported Maya ASCII files), which I was pretty happy about.


    The Beta Review also gave me some ideas to work on the next few weeks. One was finding a rectangle that can fit completely within a convex polygon. Prior to this, I was generating each footprint by shrinking the bounding box of its containing face by a random value, but in some cases (such as when the polygon is a triangle), the resulting footprint can still fall outside of the face. Another feature we thought of during the review was to subdivide a face into smaller components so the user can generate multiple smaller assets close together.

    With the end of the semester coming close, here is a list of features I'm working on having done in the next few weeks:


    Must
    • Generate a GUI for the users
    • Implement rectangle generation within convex polygon feature
    • Implement face subdivision
    • Refine building structures
    Optional
    • Implement user import of assets (as part of the GUI)
    • Add additional building types

      Dec 4 - 10
      • Implement rectangle in convex polygon
      • Implement face subdivision

      Dec 11-17
      • Refine building structures
      • Create GUI

      Dec 17-21
      • Finish optional implementations if time permits
      • Movie presentation