Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Monday, 9 December 2024

3D App Creation - A learning exercise

 Learning exercise - making a 3d app of some sort. Not sure what sort. c++ and python combo.

 


So far I've learnt about:
PyOpenGL = http://pyopengl.sourceforge.net/documentation/
GLFW = https://www.glfw.org/docs/latest/build_guide.html
vcpkg = automate dependency setup for GLFW and other libraries
vcpkg and CMake = https://vcpkg.io/en/getting-started.html
CMake Script FindGLFW3.cmake = https://cmake.org/cmake/help/latest/command/find_package.html
Wavefront OBJ = Details https://en.wikipedia.org/wiki/Wavefront_.obj_file
Lighting & Materials- OpenGL = https://learnopengl.com/Lighting/Basic-Lighting
Transformations - OpenGL = https://learnopengl.com/Getting-started/Transformations
Triangle Normal Calculation in OpenGL = https://learnopengl.com/Lighting/Basic-Lighting
OBJ Preprocessing for Compatibility = https://github.com/pywavefront/PyWavefront

Hardest part to solve - Exploding Vertices after obj import

Face Def / Quad Handling -
- OBJ files contain non-standard face definitions + use quads .
- Needed to convert quads to triangles = face definitions standardized.
- Had to remove unnecessary lines \ smoothing groups - simplify parsing.
Vertex Normalization -
- Needed to sort incorrect scaling or positioning due to varying coordinate extents = calculate (normalize) the center and maximum extent of the model
- needed to reposition and scaling vertices to fit within a view.
Missing Vertices -
- needed to use checks to skip invalid data = avoid crashing
Incomplete Triangles -
- The `pywavefront` library was, on my first attempt, returning only partial vertex data.
- Had to force triangles to adhered to a set length - for example the common graphics issue - avoiding malformed geometry.


Wednesday, 5 June 2024

learning exercise – animating explosions / projectiles with code and physics



Velocity: v0=v×(1+random.uniform(−rv,rv))v0=v×(1+random.uniform(−rv,rv))
Mass: mass=m×(1+random.uniform(−rm,rm))mass=m×(1+random.uniform(−rm,rm))
Launch Angle: random.uniform(0,360)random_angle=random.uniform(0,360)
Mess with time (bit slow to process but things look bad if not slowed down for aesthetics):
Δt=0.1speed_factor×(1+random.uniform(−time_randomize_bias,time_randomize_bias))Δt=speed_factor0.1×(1+random.uniform(−time_randomize_bias,time_randomize_bias))
Bias Launch Direction:.
angle_variation=(1−direction_bias)×90angle_variation=(1−direction_bias)×90 and
random_angle=random.uniform(launch_angle−angle_variation,launch_angle+angle_variation)random_angle=random.uniform(launch_angle−angle_variation,launch_angle+angle_variation).
Air Resistance: (1−air_resistance×Δt (delta t) /randomized_mass)
Blender testing – any 3d program really - :

Friday, 10 February 2023

Blender Auto-Rig Add-on

A test for a  Blender Add-on I've been working on in what spare time I have. I've written most of the functions and classes I need to build any rig or animation tool. The fun part is being creative with them.  Early days. 



Sunday, 26 July 2020

Python Learning in Blender- Sine expression to Drive Bone Rotation


A quick python learning exercise in blender:
  1. Scripted various controls with arguments for names/limits/shape etc
  2. Scripted a bone chain definition with arguments for names/numberOfBones/transformPlacement/axis/O.O.R etc
  3. Created a script to iterated through the bones and deliver a sine expression using the controllers Y transform as input variables for the bones XYZ rotations - sin(frame*"freq+...etc")
Links:
Now - the expression needs a little work (ie: clamp(#,#,#) etc), before I can expand upon it.

Wednesday, 2 May 2018

Blender Add-on no:1 - Texture Set Manager

I wanted a quick way to load, name and update texture sets based on selected objects so I coded this in Blender.

...as well as in Maya and Max.

I'm finding it useful for quickly flicking through textures in dense scenes and for keeping all texture sets named and organized.   

Here is a flat shaded viewport screen grab of my text scene:
Render test:



 I can switch between image types( jpg,tif,png ), sizes( SM,MD,LG ) and image sets( type of 
wood, skin, metal... etc ).  

The process of making add-ons in blender is a relatively fast and simple one:

Monday, 25 September 2017

Experiments in creating organic shapes from particle motion and curves

  1. Particle set up for testing
SETUP_NPARTICAL_MOVE

2. Turn these particles into curves. There are two ways to do this.

The first way involves expressions which allow the curves to be draw in real time. 3D Splanchnic has a tutorial showing what to put where. Watch it HERE.
code for expressions:
mel_Parts_to_curve
(update: if ( frame%10 == 0)  is simpler)
The second is a script. Bryan Woodward’s 'ParticletoTube' Script for Maya makes tubes out of particles by first creating curves. The first part of the script loops through the timeline frames for "theParticle" and then uses a nested loop to capture each "particlesPosition" and draws each curve form the "pointList". Read about the script HERE:.

Code:
partsToCurvesScript

Now curves can be generated from the particle positions:
CurvesFromParticles02

nParticles_plus_mash.jpg

3. Finally a script is needed to turn these curves into organic looking geometry. Andrew Tubelli has a nice script for doing just that. Download it from his site HERE. The code simplifies what would be an annoying task by adding a UI with a few friendly sliders:
coral2

Completing the process via the Maya UI instead of the script:
nParticles_to_poly_old_way

The code rebuilds the curves based on "arcLen", creates nParticles for the curves and evaluates a mel command to create polygons with the ability to set attributes Via a UI.


curveToGeoScript
Note: Some variable Changes are occasionally needed. For example the  curves generated by particles can be excessive - Try changing the (arcLen)*5 to say (arcLen)/5 or adding it into the UI.
I also needed to up the '.maxTriangleResolution' count.

Example:


4. A few shapes generated by moving a  passive collider around so as to alter the particle motion..
 
5. Now an experiment just from wires. I used a skull I previously modeled to draw curves on and then turned the curves into geometry.

 

Preiew render experiment
Some paint effect brushes added:

Sunday, 24 September 2017

Notes - Nodes & Mash – Maya

Here are some learning notes on creating a  plug-in for Maya, creating relationships with expressions and Maya's new python node. These are notes for me but perhaps others may stumble upon them and find them to be of interest. I'll probably change and grow this page as I learn a little more.
  1. Notes and links on how to create a Maya plug-in
Autodesk have an example Python Math Node. Here are my notes:
  • API module: import maya.openMaya
  • Proxy class access: import maya.openMayaMPx
  • Access to math module: import math
  • Variable for node name:  kPluginNodeTypeName = "nodeNameNode"
  • ID number for Node:        nodeNameNodeId = OpenMaya.MTypeId(0x00001)
  • Define subclass of existing class: class nodeName(OpenMayaMPx.MPxNode)
  • input = OpenMaya.MObject()
  • output = OpenMaya.MObject()
  • Override constructor using base: OpenMayaMPx.MPxNode.__init__(self)
  • plug = current input: def compute(self,plug,dataBlock):
  • Compute math example: result = math.sin( inputFloat )
  • Recompute plug and flag as clean: dataBlock.setClean( plug )
  • Maya pointer: return OpenMayaMPx.asMPxPtr( sineNode() )
  • Initialize method - input and output: nodeInitializer():
  • Add attribute here (ex- frequency or or amplitude): input = nAttr.create( "input", "in", ####)
  • Causes compute method to re-calculate - sets relationship: sineNode.attributeAffects( sineNode.input, sineNode.output )
  • Plug-in registration - Node Name/ID/Create Method/Initialize Method/Node Type: mplugin.registerNode( kPluginNodeTypeName, sineNodeId, nodeCreator, nodeInitializer )
  • De-register plug-in: mplugin.deregisterNode( sineNodeId)
Understanding this we can now turn these python math functions into Maya nodes:
programming-with-python.jpg
2. Some links to various resources:
Classes:
  • Wrappers - math classes - m -(Quaternion, matrix, vector, points, vectors etc)
  • MObjects - data encapsulation (meshes, skin clustter nodes, curves  etc).
  • Functions Sets - mfn  - (access and manipulate data)
  • Proxy Class - mpx - - (abstractions - create new object types - inheritance)
For memory intensive process plug-ins need to be complied in c++. Here are some links:
3. Example: Testing cosine node works.
radTimesSinCos01
radCosSonCirclesMayaNodes01
3. A Mel expression that does the exact same thing. A little bit less work :)
radTimesSinCos01_expression
Two very simple expressions that create tangent circles (also known as kissing circles).
melExpression-KissingCirclesNWJ
relationshipsWithExpressions
Nodes and expressions can build almost any kind of relationship we want.

4. Mash Python node (Maya)
mashNodes01.jpg
Python Node Test with controllers piped in as variables - Expression: (cos(t) + cos(6t)/2 + sin(14t)/3, sin(t) + sin(6t)/2 + cos(14t)/3) - (see article "Creating Art with Mathematics"). Perhaps usful patterns for stone placement or tiles of some sort.

paterns_maya_pythonNode_mash03


radCosSonCirclesMayaNodes04
paterns_maya_pythonNode_mash

Thursday, 3 August 2017

First Experiments using Grasshopper for Rhino

Grasshopper for Rhino – visual programming language/environment
 
pappusCh006
This is a blog post of notes made whilst using Grasshopper for the first time.
Circles and Triangles
Above: Solving for x²+y² = r² . Nodes used: I created two number sliders for variables - (Radius & Adjacent side), along with an expression evaluate node, square root node and vector node for XYZ.
Above: I created a Theta variable and plugged it into the Cosine(sideX) and Sine(sideY) functions, as degrees, and then into a Vector XYZ node. Math revision - SohCahToa
Above: Cos and Sin multiplied by radius.
Above: I created a variable for the radius of pivot circle and multiplied it *2 to find the center point distance of the orbiting circle. I input the arc variable as radians - rad(x).  
Note: Input for expressions = x
Above: I added a 2nd circle with the expression Acos(1/2) and added the Arc variable to it. Note that the corresponding angle is 60° .

img_0577-11.png
Unit Circle reference image above from: Inverse Trigonometric/ArcCos.

I added more circles.
rotateArchCircles04b 
Above: By shift dragging connections we can connect multiple links and post-it note style lists help visualize inputs/outputs. We could also use the merge node.

Function Curves 
Construct Domain node (DOM) - Start Value (-10) End Value (10) (= -10 to 10) 
Range Node - Give domain (-10 to 10) and steps (creates even spacing for steps within the domain - for example 10 will give a list of  steps each at 1/10th the domain).

graphsCreate2 
Interesting use of expressions for curves - see this article. I input a variety of variables, as number sliders, to create these pretty patterns.

interestingFunction02
Unit circle
2 π = 360 degrees. 1 π = 180 degrees. I created two expressions, (cos(x* π) and sin(x* π), as vectors x and y to simulate the unit circle. The range node automatically generates a 10 number list within a domain (D). When we set the domain to 2 (2 π) we get a complete rotation of our unit circle. It works the same way with a node tree instead of an expression.
unitCircExpress 
unitCircle 
unitCircNodes

Pappus Chain 
First I set up a simple relationship between three circles. As the radius of one circle increases the other decreases respectively. The magnitude of each  vector also increases or decreases to offset the change in radius . All three circles remain tangent.
papuisRing03c 
03_papuisRing03 
Next I wrote an expression to invert the top circle and tested it with some tangent lines.
papuisRing04 
03_papuisRing04
After a little bit of reading I found a number of ways to place the chain of circles. The most direct way is to calculate a three point circle from intersection points.

By extruding a number of tangent lines I was able to extract the necessary points using the curve|curve tool. Split nodes, set to integer 1, were needed to split the list generated when more then one intersection occurred.
papusCain02 
pappusChainIntersections 
03_papuisRing01 
Circle number 2 added. Interesting but not very practical.
papChainN2
With one circle created there is enough information to generate an ellipse. Math Revision - x²/a² + y²/b² =1
papsCh008
More circles added.
pappusCh006

"Series" nodes iterate versions of the top circle with 2*radius for steps. Lines from each circles center point intersect with the ellipse.

papusCain03 
There are a bunch of interesting articles about the Pappus Chain. It would be a lot of fun to dive in more deeply and explore the mathematics properly. It's a very interesting subject. See links...
Reuleaux Skyscraper
It seems that everyone who uses Grasshopper for Rhino builds a skyscraper first. So why not. I'll try a simple mathematical shape - A Reuleaux Triangle. It's an interesting enough shape.

"Rotation of a Reuleaux triangle within a square, showing also the curve traced by the center of the triangle"
Rotation_of_Reuleaux_triangle
See Wikipedia entry
A Reuleaux Triangle is a shape formed from the intersection of three circular disks, each having its center on the boundary of the other two.reuleaux_circle01c
Above:  Before and after trim using region difference nodes to extract the reuleax triangle shape.

Twisting Node tree tests

Series node with inputs to control the count (number of levels), the rotation of levels (in degrees), and the step size (size between levels)
.Untitled
More control added with rotation variables for rotating the the start and end of the building.
Untitled2
After a little more reading, and watching some youtube tutorials, I created my first grasshopper building. Not very interesting but it doesn't have to be. Its just for learning.
reuleaux_circle01D2
The node tree can be visualized with a param Viewer node which can display the tree visually - see node tree image.SkyScraperNodeTree
Grasshopper creator, David Rutton, has a video about data trees here.
datatree
Nodes of note for data manipulation/deconstruction:
 To be continued...