Grasshopper

algorithmic modeling for Rhino

Mesh Shadow Component Casts Backwards Shadows

 Hello,

 

I'm putting together a script that calculates a percentage of a surface that is shaded at various times during the day.  The backbone of this script is the mesh component.

 

However, I've run into major problems with the mesh shadow component becasue it cast shadows not only in the direction of the vector (away from the sun, like one would expect) but also opposite the direction of the vector (towards the sun, like one woule not expect).  This means I cannot use the script I've written if there is any geometry beyond the plane that catches the shadows.

 

I've tried a few dozen ways of getting around this, like cutting / culling geometry that is behind the plane (the shadows are being cast upon), but what I've ended up realizing is that I just need a component that doesn't cast backwards shadows.

 

Attached are a few images that explain this problem.  In this instance, the cube should cast a shadow on the plane, the sphere (which is opposite the plane from the "sun" should not).

mesh_shadow_script.jpg

mesh_shadow_persp.jpg

Views: 5440

Replies to This Discussion

Here is a solution.. using Dot product and Dispatch Component..

 

Attachments:

Hi Jissi

I have been recently struggling with the same problem (self casting shadows on a large objects) and I ended up with slicing breps.

I have tested your definition to see if this brings an answer but I must say with regret - it doesn't.

I've changed vector and a plane. Images attached.Looking forward to new try.

Piotr

I used Solid Differnce.. Check it..

 

Attached..

Attachments:

Hi

Using fragment of your definition I have made mine, where you can cast shadows on multiple (flat) surface from multiple breps.

It works, but it's messy (for the first time I have used path mapper) so any cleaning & simplifying actions are welcomed.

Attachments:

 

Here it is..

 

I modified the ray vector to be parametric in front direction..

 

Attachments:

Yeah I suppose that's a nasty side-effect of the code. I use the following logic to find those shadows:

Protected Overrides Sub SolveInstance(ByVal DA As Grasshopper.Kernel.IGH_DataAccess)
 Dim mesh As Mesh = Nothing
 Dim dir As Vector3d = Vector3d.Unset
 Dim plane As Plane = plane.Unset

 DA.GetData(0, mesh)
 If (Not DA.GetData(1, dir)) Then Return
 If (Not DA.GetData(2, plane)) Then Return

 If (Not dir.IsValid) OrElse _
    (Not plane.IsValid) OrElse _
    (mesh Is Nothing) Then
     Return
 End If

 Dim perp As New Plane(plane.Origin, dir)
 Dim rc As Polyline() = mesh.GetOutlines(perp)

 If (rc Is Nothing) OrElse (rc.Length = 0) Then
  AddRuntimeMessage(GH_RuntimeMessageLevel.Error, _

                               "Shadows were not cast onto the plane")
  Return
 End If

 For i As Int32 = 0 To rc.Length - 1
  Dim pline As Polyline = rc(i)

  For v As Int32 = 0 To pline.Count - 1
   Dim ray As New Line(pline(v), dir)
   Dim t As Double
   If (Rhino.Geometry.Intersect.Intersection.LinePlane(ray, plane, t)) Then
    pline(v) = ray.PointAt(t)
   End If
  Next
 Next

 DA.SetDataList(0, rc)
End Sub

If you find a good solution let me know and I'll adjust the algorithm.

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Hi David,

Maybe you can make something of this. Because of the null/paths bug it doesn't work all the time but I was trying to demonstrate it for one above one intersecting and one below.

Attachments:

If I understand well, the double loop is working on a projection, so I don't see how to immediately find out if the mesh is between the projection and the source of light or if it's the projection that is between the source of light and the mesh. The solutions I can see required to come back to the mesh. It can be done by projecting the point found (pline(v)) back on the mesh (MeshRay(mesh, ray) and then look if this point is in the same direction than the sun (dot product  equal to the product of the length (a test distance between the two points = 0 or the dot product is > 0 sounds safer here )). But I'm afraid it would consume a lot of CPU...

Another solution is to have a look at mesh.GetOutlines(plane) to see if it can easily be written into a GetOutlines(plane, dir) and then consider only the points that are in one of half space defined by plane. 

I'm sure there are better solutions. But it's very early in the morning in Europe right now and time for me to go to bed.

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service