Best way to sample noise



  • On 15/05/2014 at 01:47, xxxxxxxx wrote:

    What is the best way to sample noise (2D or 3D)?
    E.g. I have NOISE_NOISE as noise.
    What is the width and height of the noise.
    What is the size of equal colored planes?

    Which setting to use when sampling. For x in range(300) and then?
            r = p.Noise(noisetype, False, c4d.Vector(x, x, x))

    Doing so, I do get various values, but I cannot link them to a point on the noise map.
    Also, when using noisetype = c4d.NOISE_NONE I get only 0.



  • On 15/05/2014 at 04:30, xxxxxxxx wrote:

    There is a verry nice example in the docs.

      
      width = 300  
      height = 300  
      noisetype = c4d.NOISE_MOD_NOISE  
      bmp =  bitmaps.BaseBitmap()  
      bmp.Init(width, height, 24)  
      
      # Create and initialize the noise instance  
      p = C4DNoise(1234)  
      p.InitFbm(21, 2.1, 0.5)  
      
      rw = float(width-1)  
      rh = float(height-1)  
      
      # Iterate through the bitmap and set the noise value per pixel  
      for x in xrange(width) :  
          for y in xrange(height) :  
              r = p.Noise(noisetype, False, c4d.Vector(x/rw, y/rh, 0) * 7.0, octaves=5)  
              o = int(255.0*r)  
              if o < 0: o = 0  
              elif o > 255: o = 255  
      
              bmp[x, y] = (o, o, o)  
      
      bitmaps.ShowBitmap(bmp)  
      
    

    width and hight depends on the bitmap size
    like
    bmp =  bitmaps.BaseBitmap()
    bmp.Init(width, height, 24)

    the size of colored planes is in this case:
    r = p.Noise(noisetype, False, c4d.Vector(x/rw, y/rh, 0) * 7.0, octaves=0)
    size = width/7.0

    I did not understand

    link them to a point on the noise map

    Martin



  • On 15/05/2014 at 05:13, xxxxxxxx wrote:

    If you want to read a noise
    It´s always relativ to the given global scale and not a bitmap size.

      
    mat=doc.GetFirstMaterial()  
      shader=mat[c4d.MATERIAL_COLOR_SHADER]  
      print shader  
      glbsize=shader[c4d.SLA_NOISE_GLOBAL_SCALE]  
      size=shader[c4d.SLA_NOISE_SCALE]  
      print size  
      print glbsize  
      print glbsize*5/size[0], "the size of colored planes relativ to the global scale"  
    


  • On 15/05/2014 at 06:02, xxxxxxxx wrote:

    Yes, I saw the example, but I want to deform an object using a noise.
    How to map the noise to the object?



  • On 15/05/2014 at 08:07, xxxxxxxx wrote:

    That's a question of how you want to map the noise to an object. For instance, you could use
    the UV position of its points to pass to the noise function and move the point along its vertex
    normal.

    -Niklas



  • On 16/05/2014 at 01:17, xxxxxxxx wrote:

    Ok, so use the UV coordinates to get the noise value?
     r = p.Noise(noisetype, False, UV coordinates )

    Why should you move the point along it vertex normal.
    Isn't it enough to just get the noise for UV points and use that value to for example size the corresponding polygon?



  • On 16/05/2014 at 03:42, xxxxxxxx wrote:

    Thanks Niklas,

    could you please tell us how to get the specific color vlaue of the calculated uvw position?.
    I´m at this point right now:

      
    import c4d  
      
    def main() :  
      #Get shader  
      mat= doc.GetFirstMaterial()  
      shader= mat[c4d.MATERIAL_COLOR_SHADER]  
      print shader  
      noisetype= shader[c4d.SLA_NOISE_NOISE]  
      print noisetype  
        
      #Get tag  
      UVWTag= op.GetTag(c4d.Tuvw)  
      print UVWTag  
        
      #just test it for one polygon  
      for i in xrange(UVWTag.GetDataCount()-1,UVWTag.GetDataCount()) :  
          uvwdict= UVWTag.GetSlow(i)  
          #corresponding Polygon  
          corres= op.GetPolygon(i)  
          #select for testing   
          Polygons= op.GetPolygonS()  
          Polygons.Select(i)  
          print corres  
            
          p1= op.GetPoint(corres.a)  
          p2= op.GetPoint(corres.b)  
          p3= op.GetPoint(corres.c)  
          p4= op.GetPoint(corres.d)  
            
          #calculate the vertexnormals of the corresponding vertices  
          dif_p1= p1- p2  
          nor_p1= p1.Cross(dif_p1).GetNormalized()  
          print nor_p1,"nor_p1"  
          dif_p2= p2- p3  
          nor_p2= p2.Cross(dif_p2).GetNormalized()  
          print nor_p2,"nor_p2"  
          #if tris  
          if corres.d== corres.c:  
              dif_p3= p3- p1  
              nor_p3= p3.Cross(dif_p3).GetNormalized()  
              print nor_p3,"nor_p3"     
          #if quad          
          else:  
              dif_p3= p3- p4  
              nor_p3= p3.Cross(dif_p3).GetNormalized()  
              print nor_p3,"nor_p3"    
              dif_p4= p4- p1  
              nor_p4= p4.Cross(dif_p4).GetNormalized()  
              print nor_p4,"nor_p4"   
            
          #Values of UVW_Coordinates  
          print uvwdict["a"],"a"  
          print uvwdict["b"],"b"  
          print uvwdict["c"],"c"  
          print uvwdict["d"],"d"  
    

    Martin



  • On 30/05/2014 at 01:59, xxxxxxxx wrote:

    I´m not sure if there is a better solution to handle noise sampling, but
    with channel data from the render module you can read the overall shader information.

    And of course, sorry for the twaddle I posted before.
    A vertex normal could be calculated like this:

    Cheers
    Martin

      
    import c4d  
      
    from c4d import utils,Vector  
    from c4d.utils import SendModelingCommand  
      
      
    def main() :  
        
      if op== None: return  
      #convert  
      clone= SendModelingCommand(command= c4d.MCOMMAND_CURRENTSTATETOOBJECT, list= [op.GetClone()], doc= doc)  
      if not clone : return  
      obj= clone[0]  
        
      #optimize  
      opti= c4d.BaseContainer()  
      opti[c4d.MDATA_OPTIMIZE_POINTS] = True  
      SendModelingCommand(command= c4d.MCOMMAND_OPTIMIZE, list= [obj], bc= opti, doc= doc)  
        
      #triangulate the clone to ensure correct results with nonplanar quads  
      SendModelingCommand(command= c4d.MCOMMAND_TRIANGULATE, list= [obj], doc= doc)  
        
      #init neighbor class and get obj properties  
      PointCount= obj.GetPointCount()  
      PolyCount= obj.GetPolygonCount()  
      Matr= obj.GetMg()  
      nbr= utils.Neighbor()  
      nbr.Init(obj)    
        
      #set an empty list for the face normals  
      Face_N= []  
      
        
      #calculate face normals   
      for i in xrange(PolyCount) :  
            
          poly= obj.GetPolygon(i)  
          p1= obj.GetPoint(poly.a)+Matr.off  
          p2= obj.GetPoint(poly.b)+Matr.off  
          p3= obj.GetPoint(poly.c)+Matr.off  
            
      
          dif_p1= p1- p2  
          dif_p2= p2- p3  
          normal= dif_p1.Cross(dif_p2).GetNormalized()  
            
            
          Face_N.append((normal,i))  
            
            
          #for testing facenormals, calculate a matrix, test it with small cubes  
          mid_p= (p1+p2+p3)/3  
          off= mid_p  
          v3= normal  
          if abs(normal*Vector(0,1,0))<0.9999:  
               v2= normal.Cross(Vector(0,1,0)).GetNormalized()  
          else:   
              v2= normal.Cross(Vector(1,0,0)).GetNormalized()  
                
          v1= normal.Cross(v2).GetNormalized()  
            
          Face_N_Matr= c4d.Matrix(off, v1, v2, v3)  
          cube= c4d.BaseObject(c4d.Ocube)  
          cube.SetMg(Face_N_Matr)  
          cube.SetAbsScale(c4d.Vector(0.1,0.1,0.1))  
          doc.InsertObject(cube)  
        
      
      #set an empty vertex normal vector  
      Vert_N= Vector(0,0,0)  
        
      #for every point, average the neighboring facenormals to get the vertexnormal  
      for i in xrange(PointCount) :  
          Polys_P= nbr.GetPointPolys(i)  
            
          for p in Polys_P:  
              Vert_N+= Face_N[p][0]  
              print Face_N[p][0]  
          average= Vert_N/len(Polys_P)  
            
          #reset the vertex normal vector for the next point  
          Vert_N= Vector(0,0,0)  
            
            
          #calculate a matrix, test it with small cubes   
          off= obj.GetPoint(i)  
          v3= average  
          if abs(average*Vector(0,1,0))<0.9999:  
               v2= average.Cross(Vector(0,1,0)).GetNormalized()  
          else:   
              v2= average.Cross(Vector(1,0,0)).GetNormalized()  
                
          v1= average.Cross(v2).GetNormalized()  
            
          Vert_M= c4d.Matrix(off+Matr.off, v1, v2, v3)  
          cube= c4d.BaseObject(c4d.Ocube)  
          cube.SetMg(Vert_M)  
          cube.SetAbsScale(c4d.Vector(0.1,0.1,0.1))  
          doc.InsertObject(cube)  
      
      c4d.EventAdd()      
        
                 
                 
                 
            
    if __name__=='__main__':  
      main()  
      
    

Log in to reply