Code archives/3D Graphics - Mesh/PaintTriangle

This code has been declared by its author to be Public Domain code.

Download source code

PaintTriangle by TeraBit
(Posted 24 years ago)
The PaintTriangle function (with supporting functions) allows you to paint triangles on a mesh individually with the brush of your choice.
; Paint Triangle Function
; By Lee Page
; TeraBit Software
; PaintTriangle(Mesh, Surface, TriangleIndex, Brush) 
; Mesh Must be UnWelded using the Unweld(Mesh) function.


; Example of Use

Type TRIS
	Field x0#
	Field y0#
	Field z0#
	Field u0#
	Field v0#
	Field U20#
	Field V20#
	Field x1#
	Field y1#
	Field z1#
	Field u1#
	Field v1#
	Field U21#
	Field V21#
	Field x2#
	Field y2#
	Field z2#
	Field u2#
	Field v2#
	Field U22#
	Field V22#
	Field surface
End Type

Dim b(2)
Dim txv(3)

Graphics3D 640,480
Global mash, mashs
cam = CreateCamera()
cub = CreateCube()
EntityPickMode cub,2
lit = CreateLight(1)
PositionEntity lit,5,-5,3
PositionEntity cam,0,0,-5
RotateMesh cub,45,45,0
EntityFX cub,16


;***********************************
b(0) = LoadBrush ("shingle.bmp") ; *Substitute your own ones*
b(1) = LoadBrush ("oldbric.bmp") ; *Substitute your own ones*
b(2) = LoadBrush ("gothic3.bmp") ; *Substitute your own ones*
;***********************************

Unweld(cub) : UpdateNormals cub 

While Not KeyDown(1)

If KeyHit(78) And bno<2 Then bno=bno + 1
If KeyHit(74) And bno >0 Then bno=bno - 1

If MouseHit(1) Then 
	psf = CameraPick(cam,MouseX(),MouseY())
	If psf<>0 Then
		psf = PickedSurface()
		ind = PickedTriangle()
		PaintTriangle(cub,psf,ind,b(bno))
	EndIf
EndIf
TurnEntity cub,0,0.5,0

UpdateWorld
RenderWorld
Color 0,0,255
Oval MouseX(),MouseY(),5,5,False
Color 255,255,255

Text 10,10,"Brush: "+bno+" of 2."
Text 10,25,"Use + or - on Keypad to Change Brush"

Flip
Wend
End


Function unWeld(mish)
For nsurf = 1 To CountSurfaces(mish)
su=GetSurface(mish,nsurf)
For tq = 0 To CountTriangles(su)-1
txv(0) = TriangleVertex(su,tq,0)
txv(1) = TriangleVertex(su,tq,1)
txv(2) = TriangleVertex(su,tq,2)
	vq.TRIS = New TRIS
	vq\x0# = VertexX(su,txv(0))
	vq\y0# = VertexY(su,txv(0))
	vq\z0# = VertexZ(su,txv(0))
	vq\u0# = VertexU(su,txv(0),0)
	vq\v0# = VertexV(su,txv(0),0)
	vq\u20# = VertexU(su,txv(0),1)
	vq\v20# = VertexV(su,txv(0),1)
	
	vq\x1# = VertexX(su,txv(1))
	vq\y1# = VertexY(su,txv(1))
	vq\z1# = VertexZ(su,txv(1))
	vq\u1# = VertexU(su,txv(1),0)
	vq\v1# = VertexV(su,txv(1),0)
	vq\u21# = VertexU(su,txv(1),1)
	vq\v21# = VertexV(su,txv(1),1)

	vq\x2# = VertexX(su,txv(2))
	vq\y2# = VertexY(su,txv(2))
	vq\z2# = VertexZ(su,txv(2))
	vq\u2# = VertexU(su,txv(2),0)
	vq\v2# = VertexV(su,txv(2),0)
	vq\u22# = VertexU(su,txv(2),1)
	vq\v22# = VertexV(su,txv(2),1)
Next

ClearSurface su

For vq.tris = Each tris

		AddVertex su,vq\x0#,vq\y0#,vq\z0#,vq\u0#,vq\v0#
		VertexTexCoords su,mycount,vq\u20#,vq\v20#,0,1
		mycount = mycount +1

		AddVertex su,vq\x1#,vq\y1#,vq\z1#,vq\u1#,vq\v1#
		VertexTexCoords su,mycount,vq\u21#,vq\v21#,0,1
		mycount = mycount +1

		AddVertex su,vq\x2#,vq\y2#,vq\z2#,vq\u2#,vq\v2#
		VertexTexCoords su,mycount,vq\u22#,vq\v22#,0,1
		mycount = mycount +1


	AddTriangle su,mycount-3,mycount-2,mycount-1

Next

For vq.tris = Each tris
Delete vq
Next

mycount=0
Next
End Function

Function PaintTriangle(PMesh, Surfhand, Trindex, Pbrush)
	
	dest = FindSurface(pmesh,pbrush)
	If dest = 0 Then dest = CreateSurface(pmesh,pbrush)	
	vertind = CountVertices(dest)
	For p=0 To 2
	vx# = VertexX(Surfhand,TriangleVertex(Surfhand,trindex,p))
	vy# = VertexY(Surfhand,TriangleVertex(Surfhand,trindex,p))
	vZ# = VertexZ(Surfhand,TriangleVertex(Surfhand,trindex,p))
			
	u# = VertexU(Surfhand,TriangleVertex(surfhand,trindex,p),0)
	V# = VertexV(Surfhand,TriangleVertex(surfhand,trindex,p),0)
			
	lmu# = VertexU(Surfhand,TriangleVertex(Surfhand,trindex,p),1)
	lmV# = VertexV(Surfhand,TriangleVertex(Surfhand,trindex,p),1)
	
				
		AddVertex dest,vx#,vy#,vz#
		VertexTexCoords dest,vertind+p,U#,v#,0,0
		VertexTexCoords dest,vertind+p,lmu#,lmv#,0,1
	Next
	vertind = CountVertices(dest)-3
	
	AddTriangle dest,vertind,vertind+1,vertind+2
	
	removetri(Surfhand,trindex)
	UpdateNormals pmesh
End Function

Function RemoveTRI(su,TRIGONE)

For tq = 0 To CountTriangles(su)-1
txv(0) = TriangleVertex(su,tq,0)
txv(1) = TriangleVertex(su,tq,1)
txv(2) = TriangleVertex(su,tq,2)
If tq <> TRIGONE Then
	vq.TRIS = New TRIS
	vq\x0# = VertexX(su,txv(0))
	vq\y0# = VertexY(su,txv(0))
	vq\z0# = VertexZ(su,txv(0))
	vq\u0# = VertexU(su,txv(0),0)
	vq\v0# = VertexV(su,txv(0),0)
	vq\u20# = VertexU(su,txv(0),1)
	vq\v20# = VertexV(su,txv(0),1)
	
	vq\x1# = VertexX(su,txv(1))
	vq\y1# = VertexY(su,txv(1))
	vq\z1# = VertexZ(su,txv(1))
	vq\u1# = VertexU(su,txv(1),0)
	vq\v1# = VertexV(su,txv(1),0)
	vq\u21# = VertexU(su,txv(1),1)
	vq\v21# = VertexV(su,txv(1),1)

	vq\x2# = VertexX(su,txv(2))
	vq\y2# = VertexY(su,txv(2))
	vq\z2# = VertexZ(su,txv(2))
	vq\u2# = VertexU(su,txv(2),0)
	vq\v2# = VertexV(su,txv(2),0)
	vq\u22# = VertexU(su,txv(2),1)
	vq\v22# = VertexV(su,txv(2),1)
	
EndIf
Next

ClearSurface su

For vq.tris = Each tris

		AddVertex su,vq\x0#,vq\y0#,vq\z0#,vq\u0#,vq\v0#
		VertexTexCoords su,mycount,vq\u20#,vq\v20#,0,1
		mycount = mycount +1

		AddVertex su,vq\x1#,vq\y1#,vq\z1#,vq\u1#,vq\v1#
		VertexTexCoords su,mycount,vq\u21#,vq\v21#,0,1
		mycount = mycount +1

		AddVertex su,vq\x2#,vq\y2#,vq\z2#,vq\u2#,vq\v2#
		VertexTexCoords su,mycount,vq\u22#,vq\v22#,0,1
		mycount = mycount +1


	AddTriangle su,mycount-3,mycount-2,mycount-1

Next

For vq.tris = Each tris
Delete vq
Next
End Function

Comments

Beaker
(Posted 21 years ago)
Improved version below. Fixed some bugs, removed redundant stuff, added vertex normals (no need to UpdateNormals anymore), added delete example, and weld function (from here:
http://www.blitzbasic.com/codearcs/codearcs.php?code=454 )

I also added an example of re-welding vertices (hit SPACE bar). Enjoy.

; Paint/Delete Triangle Function
; By Lee Page
; TeraBit Software
; [amendments and bugfixes by Beaker]
; PaintTriangle(Mesh, Surface, TriangleIndex, Brush) 
; Mesh Must be UnWelded using the Unweld(Mesh) function.


; Example of Use

Type TRIS
	Field x0#
	Field y0#
	Field z0#
	Field u0#
	Field v0#
	Field U20#
	Field V20#
	Field nx0#
	Field ny0#
	Field nz0#

	Field x1#
	Field y1#
	Field z1#
	Field u1#
	Field v1#
	Field U21#
	Field V21#
	Field nx1#
	Field ny1#
	Field nz1#

	Field x2#
	Field y2#
	Field z2#
	Field u2#
	Field v2#
	Field U22#
	Field V22#
	Field nx2#
	Field ny2#
	Field nz2#

	Field surface
End Type

Dim b(2)
Dim txv(3)

Graphics3D 640,480
cam = CreateCamera()
cub = CreateCube()
EntityPickMode cub,2
lit = CreateLight(1)
PositionEntity lit,5,-5,3
PositionEntity cam,0,0,-5
RotateMesh cub,45,45,0
EntityFX cub,16


;***********************************
b(0) = CreateBrush(255,0,0 );LoadBrush ("shingle.bmp") ; *Substitute your own ones*
b(1) = CreateBrush(0,255,0 );LoadBrush ("oldbric.bmp") ; *Substitute your own ones*
b(2) = CreateBrush(0,0,255 );LoadBrush ("gothic3.bmp") ; *Substitute your own ones*
;***********************************

Unweld(cub) 

While Not KeyDown(1)

	If KeyHit(78) And bno<2 Then bno=bno + 1
	If KeyHit(74) And bno >0 Then bno=bno - 1
	
	If MouseHit(1) Then 
		psf = CameraPick(cam,MouseX(),MouseY())
		If psf<>0 Then
			psf = PickedSurface()
			ind = PickedTriangle()
			PaintTriangle(cub,psf,ind,b(bno))
		EndIf
	EndIf
	
	If MouseHit(2) Then 
		psf = CameraPick(cam,MouseX(),MouseY())
		If psf<>0 Then
			psf = PickedSurface()
			ind = PickedTriangle()
			removeTRI(psf,ind)
		EndIf
	EndIf

	If KeyDown(57)
		weld(cub)
	EndIf

	
	TurnEntity cub,0,0.5,0
	
	UpdateWorld
	RenderWorld
	Color 0,0,255
	Oval MouseX(),MouseY(),5,5,False
	Color 255,255,255
	
	Text 10,10,"Brush: "+bno+" of 2.  verts "+CountVertices(GetSurface(cub,1))+" tris "+CountTriangles(GetSurface(cub,1))
	Text 10,25,"Use + or - on Keypad to Change Brush"
	
	Flip
Wend
End


Function unWeld(mish)
	For nsurf = 1 To CountSurfaces(mish)
		su=GetSurface(mish,nsurf)
		For tq = 0 To CountTriangles(su)-1
		txv(0) = TriangleVertex(su,tq,0)
		txv(1) = TriangleVertex(su,tq,1)
		txv(2) = TriangleVertex(su,tq,2)

		vq.TRIS = New TRIS
		vq\x0# = VertexX(su,txv(0))
		vq\y0# = VertexY(su,txv(0))
		vq\z0# = VertexZ(su,txv(0))
		vq\u0# = VertexU(su,txv(0),0)
		vq\v0# = VertexV(su,txv(0),0)
		vq\u20# = VertexU(su,txv(0),1)
		vq\v20# = VertexV(su,txv(0),1)

		vq\nx0 = VertexNX(su,txv(0))
		vq\ny0 = VertexNY(su,txv(0))
		vq\nz0 = VertexNZ(su,txv(0))
		
		vq\x1# = VertexX(su,txv(1))
		vq\y1# = VertexY(su,txv(1))
		vq\z1# = VertexZ(su,txv(1))
		vq\u1# = VertexU(su,txv(1),0)
		vq\v1# = VertexV(su,txv(1),0)
		vq\u21# = VertexU(su,txv(1),1)
		vq\v21# = VertexV(su,txv(1),1)

		vq\nx1 = VertexNX(su,txv(1))
		vq\ny1 = VertexNY(su,txv(1))
		vq\nz1 = VertexNZ(su,txv(1))
	
		vq\x2# = VertexX(su,txv(2))
		vq\y2# = VertexY(su,txv(2))
		vq\z2# = VertexZ(su,txv(2))
		vq\u2# = VertexU(su,txv(2),0)
		vq\v2# = VertexV(su,txv(2),0)
		vq\u22# = VertexU(su,txv(2),1)
		vq\v22# = VertexV(su,txv(2),1)

		vq\nx2 = VertexNX(su,txv(2))
		vq\ny2 = VertexNY(su,txv(2))
		vq\nz2 = VertexNZ(su,txv(2))
	Next
	
	ClearSurface su
	
	For vq.tris = Each tris
	
		AddVertex su,vq\x0#,vq\y0#,vq\z0#,vq\u0#,vq\v0#
		VertexTexCoords su,mycount,vq\u20#,vq\v20#,0,1
		VertexNormal su,mycount,vq\nx0,vq\ny0,vq\nz0
		mycount = mycount +1

		AddVertex su,vq\x1#,vq\y1#,vq\z1#,vq\u1#,vq\v1#
		VertexTexCoords su,mycount,vq\u21#,vq\v21#,0,1
		VertexNormal su,mycount,vq\nx1,vq\ny1,vq\nz1
		mycount = mycount +1

		AddVertex su,vq\x2#,vq\y2#,vq\z2#,vq\u2#,vq\v2#
		VertexTexCoords su,mycount,vq\u22#,vq\v22#,0,1
		VertexNormal su,mycount,vq\nx2,vq\ny2,vq\nz2
		mycount = mycount +1
	
	
		AddTriangle su,mycount-3,mycount-2,mycount-1
	
	Next
	
	Delete Each tris
	
	mycount=0
	Next
End Function

Function PaintTriangle(PMesh, Surfhand, Trindex, Pbrush)
	
	dest = FindSurface(pmesh,pbrush)
	If dest = 0 Then dest = CreateSurface(pmesh,pbrush)	
	vertind = CountVertices(dest)
	For p=0 To 2
		vx# = VertexX(Surfhand,TriangleVertex(Surfhand,trindex,p))
		vy# = VertexY(Surfhand,TriangleVertex(Surfhand,trindex,p))
		vZ# = VertexZ(Surfhand,TriangleVertex(Surfhand,trindex,p))
				
		u# = VertexU(Surfhand,TriangleVertex(surfhand,trindex,p),0)
		V# = VertexV(Surfhand,TriangleVertex(surfhand,trindex,p),0)
				
		lmu# = VertexU(Surfhand,TriangleVertex(Surfhand,trindex,p),1)
		lmV# = VertexV(Surfhand,TriangleVertex(Surfhand,trindex,p),1)

		nx# = VertexNX(Surfhand,TriangleVertex(Surfhand,trindex,p))
		ny# = VertexNY(Surfhand,TriangleVertex(Surfhand,trindex,p))
		nz# = VertexNZ(Surfhand,TriangleVertex(Surfhand,trindex,p))
				
		AddVertex dest,vx#,vy#,vz#
		VertexTexCoords dest,vertind+p,U#,v#,0,0
		VertexTexCoords dest,vertind+p,lmu#,lmv#,0,1
		VertexNormal dest,vertind+p,nx,ny,nz
	Next
	vertind = CountVertices(dest)-3
	
	AddTriangle dest,vertind,vertind+1,vertind+2
	
	removetri(Surfhand,trindex)
End Function

Function RemoveTRI(su,TRIGONE)

	For tq = 0 To CountTriangles(su)-1
		txv(0) = TriangleVertex(su,tq,0)
		txv(1) = TriangleVertex(su,tq,1)
		txv(2) = TriangleVertex(su,tq,2)
		If tq <> TRIGONE Then
			vq.TRIS = New TRIS
			vq\x0# = VertexX(su,txv(0))
			vq\y0# = VertexY(su,txv(0))
			vq\z0# = VertexZ(su,txv(0))
			vq\u0# = VertexU(su,txv(0),0)
			vq\v0# = VertexV(su,txv(0),0)
			vq\u20# = VertexU(su,txv(0),1)
			vq\v20# = VertexV(su,txv(0),1)
	
			vq\nx0 = VertexNX(su,txv(0))
			vq\ny0 = VertexNY(su,txv(0))
			vq\nz0 = VertexNZ(su,txv(0))
			
			vq\x1# = VertexX(su,txv(1))
			vq\y1# = VertexY(su,txv(1))
			vq\z1# = VertexZ(su,txv(1))
			vq\u1# = VertexU(su,txv(1),0)
			vq\v1# = VertexV(su,txv(1),0)
			vq\u21# = VertexU(su,txv(1),1)
			vq\v21# = VertexV(su,txv(1),1)
	
			vq\nx1 = VertexNX(su,txv(1))
			vq\ny1 = VertexNY(su,txv(1))
			vq\nz1 = VertexNZ(su,txv(1))
		
			vq\x2# = VertexX(su,txv(2))
			vq\y2# = VertexY(su,txv(2))
			vq\z2# = VertexZ(su,txv(2))
			vq\u2# = VertexU(su,txv(2),0)
			vq\v2# = VertexV(su,txv(2),0)
			vq\u22# = VertexU(su,txv(2),1)
			vq\v22# = VertexV(su,txv(2),1)
	
			vq\nx2 = VertexNX(su,txv(2))
			vq\ny2 = VertexNY(su,txv(2))
			vq\nz2 = VertexNZ(su,txv(2))
			
		EndIf
	Next

	ClearSurface su
	
	For vq.tris = Each tris
	
		AddVertex su,vq\x0#,vq\y0#,vq\z0#,vq\u0#,vq\v0#
		VertexTexCoords su,mycount,vq\u20#,vq\v20#,0,1
		VertexNormal su,mycount,vq\nx0,vq\ny0,vq\nz0
		mycount = mycount +1

		AddVertex su,vq\x1#,vq\y1#,vq\z1#,vq\u1#,vq\v1#
		VertexTexCoords su,mycount,vq\u21#,vq\v21#,0,1
		VertexNormal su,mycount,vq\nx1,vq\ny1,vq\nz1
		mycount = mycount +1

		AddVertex su,vq\x2#,vq\y2#,vq\z2#,vq\u2#,vq\v2#
		VertexTexCoords su,mycount,vq\u22#,vq\v22#,0,1
		VertexNormal su,mycount,vq\nx2,vq\ny2,vq\nz2
		mycount = mycount +1
	
	
		AddTriangle su,mycount-3,mycount-2,mycount-1
	
	Next
	
	Delete Each tris
End Function


;=========== WELD =================================================


Function Weld(mish)
	
;	RenderWorld : Text GraphicsWidth()/2,GraphicsHeight()/2,"Optimising Please Wait..",True,True : Flip  
	
	For nsurf = 1 To CountSurfaces(mish)
		su=GetSurface(mish,nsurf)
		For tq = 0 To CountTriangles(su)-1
			txv(0) = TriangleVertex(su,tq,0)
			txv(1) = TriangleVertex(su,tq,1)
			txv(2) = TriangleVertex(su,tq,2)
	
			vq.TRIS = New TRIS
			
			vq\x0# = VertexX(su,txv(0))
			vq\y0# = VertexY(su,txv(0))
			vq\z0# = VertexZ(su,txv(0))
			vq\u0# = VertexU(su,txv(0),0)
			vq\v0# = VertexV(su,txv(0),0)
			vq\u20# = VertexU(su,txv(0),1)
			vq\v20# = VertexV(su,txv(0),1)
	
			vq\nx0 = VertexNX(su,txv(0))
			vq\ny0 = VertexNY(su,txv(0))
			vq\nz0 = VertexNZ(su,txv(0))
			
			vq\x1# = VertexX(su,txv(1))
			vq\y1# = VertexY(su,txv(1))
			vq\z1# = VertexZ(su,txv(1))
			vq\u1# = VertexU(su,txv(1),0)
			vq\v1# = VertexV(su,txv(1),0)
			vq\u21# = VertexU(su,txv(1),1)
			vq\v21# = VertexV(su,txv(1),1)
	
			vq\nx1 = VertexNX(su,txv(1))
			vq\ny1 = VertexNY(su,txv(1))
			vq\nz1 = VertexNZ(su,txv(1))
		
			vq\x2# = VertexX(su,txv(2))
			vq\y2# = VertexY(su,txv(2))
			vq\z2# = VertexZ(su,txv(2))
			vq\u2# = VertexU(su,txv(2),0)
			vq\v2# = VertexV(su,txv(2),0)
			vq\u22# = VertexU(su,txv(2),1)
			vq\v22# = VertexV(su,txv(2),1)
	
			vq\nx2 = VertexNX(su,txv(2))
			vq\ny2 = VertexNY(su,txv(2))
			vq\nz2 = VertexNZ(su,txv(2))
		Next
		
		ClearSurface su
		
		For vq.tris = Each tris
		
			vt1=Findvert(su,vq\x0#,vq\y0#,vq\z0#,vq\u0#,vq\v0#,vq\u20#,vq\v20#,vq\nx0,vq\ny0,vq\nz0)
			
			If vt1=-1 Then
				AddVertex su,vq\x0#,vq\y0#,vq\z0#,vq\u0#,vq\v0#
				VertexTexCoords su,mycount,vq\u20#,vq\v20#,0,1
				VertexNormal su,mycount,vq\nx0,vq\ny0,vq\nz0
				vt1 = mycount
				mycount = mycount +1
			EndIf
	
			vt2=findvert(su,vq\x1#,vq\y1#,vq\z1#,vq\u1#,vq\v1#,vq\u21#,vq\v21#,vq\nx1,vq\ny1,vq\nz1)
			If Vt2=-1 Then
				AddVertex su,vq\x1#,vq\y1#,vq\z1#,vq\u1#,vq\v1#
				VertexTexCoords su,mycount,vq\u21#,vq\v21#,0,1
				VertexNormal su,mycount,vq\nx1,vq\ny1,vq\nz1
				vt2 = mycount
				mycount = mycount +1
			EndIf
			
			vt3=findvert(su,vq\x2#,vq\y2#,vq\z2#,vq\u2#,vq\v2#,vq\u22#,vq\v22#,vq\nx2,vq\ny2,vq\nz2)
			
			If vt3=-1 Then 
				AddVertex su,vq\x2#,vq\y2#,vq\z2#,vq\u2#,vq\v2#
				VertexTexCoords su,mycount,vq\u22#,vq\v22#,0,1
				VertexNormal su,mycount,vq\nx2,vq\ny2,vq\nz2
				vt3 = mycount
				mycount = mycount +1
			EndIf
		
			AddTriangle su,vt1,vt2,vt3
		
		Next
		
		Delete Each tris
		mycount=0
	Next
End Function


Function findvert(su,x2#,y2#,z2#,u2#,v2#,u22#,v22#,nx#,ny#,nz#)
	Local EPS# = 0.000001
	For t=0 To CountVertices(su)-1
		If Abs(VertexX(su,t)-x2) < EPS 
			If Abs(VertexY(su,t)-y2) < EPS 
				If Abs(VertexZ(su,t)-z2) < EPS 
					If Abs(VertexU(su,t,0)-u2) < EPS 
						If Abs(VertexV(su,t,0)-v2) < EPS 
							If Abs(VertexNX(su,t) - nx) < EPS
								If Abs(VertexNY(su,t) - ny) < EPS
									If Abs(VertexNZ(su,t) - nz) < EPS
;										If Abs(VertexU(su,t,1)-u22) < EPS 
;											If Abs(VertexV(su,t,1)-v22) < EPS
												Return t
;											EndIf
;										EndIf
									EndIf
								EndIf
							EndIf
						EndIf
					EndIf
				EndIf
			EndIf
		EndIf
	Next
	Return -1
End Function


Code Archives Forum