티스토리 뷰

TouchDesigner

TOUCHDESIGNER _ RANDOM GENERATOR

잉_민 2024. 4. 25. 00:55

randomCHOP1.tox
0.00MB
EXTENSION

RandExt 라는 extension을 임포트함.

base 자체에 random 이라는 커스텀 탭을 만들었음.

base 변수 설정 **

이 아래 .local 이라는 base는 뭔지 모르겠지만. 여기에 설정된 값들 때문에 randomCHOP1안에 있는 노드들이 작동함.(?)

ableton 관련인듯..?

 

randomCHOP1 내부 노드들

RandExt = text 노드

parexec1 = Parameter excute 노드.

Seed 변화감지
samples range int?float? unique?
상위 노드 : base

RandExt 는 값을 받아오는 형태 ( base에 설정된 파라미터 값을 받아옴.)

 Parameter excute는 def onValueChange(par, prev) 함수를 통해서 변화를 감지함.

 

**CHOP : scrip는 스크립트 콜백 노드를 통해서 시그널을 생성함.

https://docs.derivative.ca/ScriptCHOP_Class

 

ScriptCHOP Class

To re-compute the output data of the Operators. An operator cooks when (1) its inputs change, (2) its Parameters change, (3) when the timeline moves forward in some cases, or (4) Scripting commands are run on the node. When the operator is a Panel Componen

docs.derivative.ca

parent()

여기서 부모가 base 인듯?( randomCHOP1 )

scriptOp

TouchDesigner에서 Script CHOP 오퍼레이터(OP)를 참조하는 용어

데이터 처리 및 생성: 스크립트 오퍼레이터는 데이터를 처리하고 새로운 채널 데이터를 생성할 수 있습니다. 예를 들어, 입력된 오디오 신호를 분석하거나 새로운 비디오 프레임 데이터를 생성하는 등의 작업이 가능합니다.
동적 파라미터 조정: 스크립트를 통해 동적으로 파라미터를 추가하거나 수정할 수 있습니다. 이는 사용자 인터페이스에서 동적으로 조작할 수 있는 컨트롤을 제공하거나, 노드의 동작을 사용자의 입력에 따라 조정할 수 있게 합니다.
콜백 함수 실행: onCook, onPulse 등의 콜백 함수를 정의하여 특정 이벤트가 발생했을 때 코드가 실행되도록 할 수 있습니다. 이를 통해 사용자가 인터페이스에서 버튼을 누르거나, 특정 조건이 만족될 때 특정 동작을 실행하게 할 수 있습니다.

 "cook"

특정 노드가 처리 또는 업데이트 과정을 거치는 것을 의미

 

 

setupParameters 에서는 커스텀 페이지를 만든다. 여기서 페이지는 새로운 탭 환경을 말하는듯.

append 하면 추가. par 파라미터 Int 인트값. Samples 인트값 변수를 만들어줌. Custom 페이지에 

하지만 버튼이 만들어져있음..

on Pulse 함수

타입 파라미터가 눌러질 때(즉, 활성화되거나 트리거될 때) 호출

사용자 인터페이스 요소와 같이 특정 작업을 즉각적으로 실행해야 할 때

 

fetch() 함수


키에 대한 값을 검색: 스토리지에서 주어진 키에 대한 값을 찾습니다.
기본값 반환: 키가 존재하지 않을 경우, 호출자가 제공한 기본값을 반환합니다.
스크립트와의 상호작용: 스크립트 내 다른 로직과의 데이터 교환을 위해 사용됩니다.

 

"채널", "샘플", 그리고 "값(value)"은 주로 CHOP(Channel Operators) 내에서 데이터를 다루는 방식에 대한 용어

채널 (Channel)
채널은 연속적인 데이터 값의 시퀀스를 나타냅니다. 예를 들어, 오디오 신호에서 각 채널은 시간에 따른 오디오 레벨의 연속적인 샘플을 포함할 수 있습니다. 

샘플 (Sample)
샘플은 채널 내의 개별 데이터 포인트를 말합니다. 즉, 특정 시간에 채널의 값 하나를 나타냅니다. 예를 들어, 채널이 시간에 따른 온도의 변화를 나타낸다면, 각 샘플은 특정 시간에서의 온도를 나타냅니다. 샘플은 보통 일정한 시간 간격으로 측정되며, 이 간격은 채널의 "샘플 레이트"에 의해 결정됩니다.

값 (Value)
값은 각 샘플의 실제 데이터를 의미합니다. 즉, 채널의 특정 시점에서의 데이터 포인트입니다. 은 숫자일 수도 있고, 더 복잡한 데이터 구조를 가질 수도 있습니다. 예를 들어, 3D 좌표를 나타내는 채널은 각 샘플에서 X, Y, Z의 세 개의 값(좌표)을 가질 수 있습니다.


채널: 데이터의 연속적인 스트림을 정의하며, 여러 개의 샘플을 포함합니다.
샘플: 채널에서의 개별적인 데이터 포인트로, 각각의 시간에 해당하는 값을 가집니다.
값: 샘플에 저장된 실제 데이터(값)입니다.

# me is this DAT.
# 
# scriptOp is the OP which is cooking.

# press 'Setup Parameters' in the OP to call this function to re-create the parameters.

def setupParameters(scriptOp):
	scriptOp.appendParInt('Samples', page='Custom')

	return

# called whenever custom pulse parameter is pushed
def onPulse(par):

	# get value from custom parameter
	numSamples = parent().par.Samples.eval()
	# 베이스노드에 설정된 Samples 갯수 받아옴
	print(parent().par.Samples)

	newchan = [0]*numSamples # 새 채널 데이터 초기화
	
	#랜덤 값 생성 로직 ****
	rlo = min(parent().par.Range1, parent().par.Range2) #range low
	rhi = max(parent().par.Range1, parent().par.Range2) #range high
	
	prev_values = me.fetch('values',[None]) #이전값 저장, 키에 연결된 값을 가져옴

	#이전값과 비교 , 유니크 값 생성
	if len(prev_values) >= numSamples:
		prev_values = prev_values[:numSamples]
	else:
		prev_values.extend([None]*(numSamples-len(prev_values)))

	for i in range(numSamples):
		prev_rand = prev_values[i]
		
		if abs(rlo-rhi) != 0:
		#do while
			while True:
				if not parent().par.Intfloat:
					try:
						rand = parent().RandInt(rlo, rhi)
					except:
						nrlo = int(rlo)
						nrhi = int(rhi)
						if abs(nrlo-nrhi) == 0:
							rand = nrlo
							break
						else:
							rand = parent().RandInt(nrlo, nrhi)
				else:
					rand = parent().Uniform(rlo, rhi)
				
				if prev_rand == None or rand != prev_rand or not parent().par.Unique:
					break			
		else: 
			rand = rlo
			
		newchan[i] = rand

	me.store('values',newchan)
	me.store('numSamples',numSamples)
	return

def cook(scriptOp):
	scriptOp.clear()
	
	# get value from custom parameter
	scriptOp.numSamples = me.fetch('numSamples', 1)

	newchan = scriptOp.appendChan(parent().par.Channelname.eval())
	# 값 할당하기
	values = me.fetch('values',[0]*scriptOp.numSamples)
	values = values[:scriptOp.numSamples]
	for i in range(scriptOp.numSamples):
		newchan[i] = values[i]
	return

def onSetupParameters(scriptOp):
# 초기 파라미터 설정을 자동으로 구성
#'Randomize'라는 이름의 파라미터 페이지와 버튼을 생성
	"""Auto-generated by Component Editor"""
	# manual changes to anything other than parJSON will be	# destroyed by Comp Editor unless doc string above is	# changed

	TDJSON = op.TDModules.mod.TDJSON
	parJSON = """
	{
		"Custom": {
			"Randomize": {
				"name": "Randomize",
				"label": "Randomize",
				"page": "Custom",
				"style": "Pulse",
				"default": false,
				"enable": true,
				"startSection": false,
				"readOnly": false,
				"enableExpr": null,
				"help": ""
			}
		}
	}
	"""
	parData = TDJSON.textToJSON(parJSON)
	TDJSON.addParametersFromJSONOp(scriptOp, parData, destroyOthers=True)

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함