void PlotDefC::ChangeView(const Coord3D& scaleFactor) { Coord3D viewCenter = GetNewViewCenter(); if (viewCenter.CoordIsNull()) return; Limit3D oldLimits = GetCurrentViewLimits(); Limit3D newLimits; PC_ViewOpRec axesSettings = GetPlotViewOps(); DoOp(axesSettings.xOp, viewCenter.cX, oldLimits.minLim.cX, oldLimits.maxLim.cX, scaleFactor.cX, newLimits.minLim.cX, newLimits.maxLim.cX); DoOp(axesSettings.yOp, viewCenter.cY, oldLimits.minLim.cY, oldLimits.maxLim.cY, scaleFactor.cY, newLimits.minLim.cY, newLimits.maxLim.cY); DoOp(axesSettings.zOp, viewCenter.cZ, oldLimits.minLim.cZ, oldLimits.maxLim.cZ, scaleFactor.cZ, newLimits.minLim.cZ, newLimits.maxLim.cZ); // keep existing 3D az/scale/el PC_View currView = GetCurrentView(); // clear translations currView.translation = Coord3D(0.0); // set new limits currView.viewLimits = newLimits; plotViews.PushStack(currView); ResetView(); }
double CSurface3DFrame::operator()(double X, double Y) { CSingleLock Lock(&m_p3D->m_TheLock, true); m_p3D->m_nCalls++; CSurface3DFrame *pFrame; double Val=DoOp(X, Y, pFrame); if (CSurfaceCommon::m_DoSmoothing) { double dx=pFrame->m_dDivWidthX*pFrame->m_nDivsX/6; double dy=pFrame->m_dDivWidthY*pFrame->m_nDivsY/6; double x1=X-dx; double x2=X+dx; double y1=Y-dy; double y2=Y+dy; CSurface3DFrame *pElement1, *pElement2, *pElement3, *pElement4; double Val1=DoOp(X-dx, Y-dy, pElement1); double Val2=DoOp(X-dx, Y+dy, pElement2); double Val3=DoOp(X+dx, Y+dy, pElement3); double Val4=DoOp(X+dx, Y-dy, pElement4); Val=0.25*(Val1+Val2+Val3+Val4); // if (pElement2->m_iLevel!=pElement1->m_iLevel || // pElement3->m_iLevel!=pElement1->m_iLevel || // pElement4->m_iLevel!=pElement1->m_iLevel) // { // int x=0; // dbgpln("Smooth Level Mismatch %i %i %i %i %i", // pFrame->m_iLevel, pElement1->m_iLevel, pElement2->m_iLevel, pElement3->m_iLevel, pElement4->m_iLevel); // } // Val=0.25*(Val1+Val2+Val3+Val4); int xxx=0; } return Val; }
Vasp *VaspOp::m_cpowi(OpParam &p,CVasp &src,const Argument &arg,CVasp *dst) { Vasp *ret = NULL; CVecBlock *vecs = GetCVecs(p.opname,src,dst); if(vecs) { I powi = 1; if(arg.IsList() && arg.GetList().Count() >= 1 && flext::CanbeInt(arg.GetList()[0])) powi = flext::GetAInt(arg.GetList()[0]); else post("%s - power arg is invalid -> set to 1",p.opname); if(powi < 0) { post("%s - negative integer power is not allowed",p.opname); } else { switch(powi) { case 0: { p.cbin.rarg = 1,p.cbin.iarg = 0; ret = DoOp(vecs,VecOp::d_cset,p); break; } case 1: { // set arg to src ret = DoOp(vecs,VecOp::d_ccopy,p); break; } case 2: { ret = DoOp(vecs,VecOp::d_csqr,p); break; } default: { p.ibin.arg = powi; ret = DoOp(vecs,VecOp::d_cpowi,p); break; } } } delete vecs; } return ret; }
/*! \brief Finds peaks or valleys by radius in a complex vasp. \param arg argument list \param arg.rep repetition count \param dst destination vasp (NULL for in-place operation) \param inv true for valley operation \return normalized destination vasp */ Vasp *VaspOp::m_rpeaks(OpParam &p,CVasp &src,CVasp *dst,BL inv) { Vasp *ret = NULL; CVecBlock *vecs = GetCVecs(p.opname,src,dst); if(vecs) { p.peaks.cx = true; ret = DoOp(vecs,inv?d_rvalleys:d_rpeaks,p); delete vecs; } return ret; }
Vasp *VaspOp::m_ccopy(OpParam &p,CVasp &src,CVasp &arg) { Vasp *s = NULL,*d = NULL; CVecBlock *vecs = GetCVecs(p.opname,src,&arg); if(vecs) { d = DoOp(vecs,VecOp::d_ccopy,p); s = vecs->SrcVasp(); if(d) arg = *d; else { arg.Clear(); delete d; } delete vecs; } return s; }
void MHIntegerAction::Perform(MHEngine *engine) { MHUnion targetVal; // Find the target and get its current value. The target can be an indirect reference. MHObjectRef parm; m_Target.GetValue(parm, engine); MHRoot *pTarget = engine->FindObject(parm); pTarget->GetVariableValue(targetVal, engine); targetVal.CheckType(MHUnion::U_Int); // Get the value of the operand. int nOperand = m_Operand.GetValue(engine); // Set the value of targetVal to the new value and store it. targetVal.m_nIntVal = DoOp(targetVal.m_nIntVal, nOperand); pTarget->SetVariableValue(targetVal); }
Vasp *VaspOp::m_radd(OpParam &p,CVasp &src,const Argument &arg,CVasp *dst) { Vasp *ret = NULL; CVecBlock *vecs = GetCVecs(p.opname,src,dst); if(vecs) { if(arg.IsList() && arg.GetList().Count() >= 1 && flext::CanbeFloat(arg.GetList()[0])) p.cbin.rarg = flext::GetAFloat(arg.GetList()[0]); else { post("%s - argument is invalid -> set to 0",p.opname); p.cbin.rarg = 0; } p.cbin.iarg = 0; // not used anyway ret = DoOp(vecs,VecOp::d_radd,p); delete vecs; } return ret; }
/*! \brief Does vasp resampling. \param arg argument list \param arg.factor factor for resampling \param arg.center center of resampling \param dst destination vasp (NULL for in-place operation) \param symm true for symmetric operation \param mode interpolation mode \return normalized destination vasp */ Vasp *VaspOp::m_tilt(OpParam &p,CVasp &src,const Argument &arg,CVasp *dst,BL symm) { Vasp *ret = NULL; if(arg.IsList() && arg.GetList().Count() >= 1) { RVecBlock *vecs = GetRVecs(p.opname,src,dst); if(vecs) { p.tilt.factor = flext::GetAFloat(arg.GetList()[0]); p.tilt.center = arg.GetList().Count() >= 2?flext::GetAFloat(arg.GetList()[1]):0; ret = DoOp(vecs,VecOp::d_tilt,p,symm); delete vecs; } } else post("%s - no arguments: no operation",p.opName()); return ret; }
/*! \brief vasp shift or rotation \todo units for shift */ Vasp *VaspOp::m_shift(OpParam &p,CVasp &src,const Argument &arg,CVasp *dst,BL shift,BL symm) { Vasp *ret = NULL; RVecBlock *vecs = GetRVecs(p.opname,src,dst); if(vecs) { if(arg.IsList() && arg.GetList().Count() >= 1 && flext::CanbeFloat(arg.GetList()[0])) { // shift length p.sh.sh = flext::GetAFloat(arg.GetList()[0]); } else { post("%s - invalid argument -> set to 0",p.opname); p.sh.sh = 0; } ret = DoOp(vecs,shift?VecOp::d_shift:VecOp::d_rot,p,symm); delete vecs; } return ret; }
uint32 InterpretedVM::Execute(Function* func) { prog.CurrentFunction = func; int pc = 0; for (;;) { auto op = func->Ops[pc]; switch (op.Op) { case Op::OpBranch: { auto branch = (SBranch*)op.Memory; pc = func->Labels.at(branch->TargetLabelId); break; } case Op::OpBranchConditional: { auto branch = (SBranchConditional*)op.Memory; uint32 labelID; Value val = Dereference(env.Values[branch->ConditionId]); if (*(bool*)val.Memory) { labelID = branch->TrueLabelId; } else { labelID = branch->FalseLabelId; } pc = func->Labels.at(labelID); break; } case Op::OpFunctionCall: { auto call = (SFunctionCall*)op.Memory; Function toCall = prog.FunctionDefinitions.at(call->FunctionId); for (int i = 0; i < call->ArgumentIdsCount; i++) { env.Values[toCall.Parameters[i].ResultId] = Dereference(env.Values.at(call->ArgumentIds[i])); } uint32 resultId = Execute(&toCall); if (resultId == -1) { return -1; } prog.CurrentFunction = func; env.Values[call->ResultId] = env.Values[resultId]; break; } case Op::OpExtInst: { auto extInst = (SExtInst*)op.Memory; Value* ops = new Value[extInst->OperandIdsCount]; for (int i = 0; i < extInst->OperandIdsCount; i++) { ops[i] = Dereference(env.Values.at(extInst->OperandIds[i])); } ExtInstFunc* func = env.Extensions[extInst->SetId][extInst->Instruction]; env.Values[extInst->ResultId] = func(this, extInst->ResultTypeId, extInst->OperandIdsCount, ops); break; } case Op::OpConvertSToF: { auto convert = (SConvertSToF*)op.Memory; Value op1 = Dereference(env.Values[convert->SignedValueId]); env.Values[convert->ResultId] = DoOp(convert->ResultTypeId, Convert<int32, float>, op1); break; } case Op::OpFAdd: { auto add = (SFAdd*)op.Memory; Value op1 = Dereference(env.Values[add->Operand1Id]); Value op2 = Dereference(env.Values[add->Operand2Id]); env.Values[add->ResultId] = DoOp(add->ResultTypeId, Add<float>, op1, op2); break; } case Op::OpIAdd: { auto add = (SIAdd*)op.Memory; Value op1 = Dereference(env.Values[add->Operand1Id]); Value op2 = Dereference(env.Values[add->Operand2Id]); env.Values[add->ResultId] = DoOp(add->ResultTypeId, Add<int>, op1, op2); break; } case Op::OpFSub: { auto sub = (SFSub*)op.Memory; Value op1 = Dereference(env.Values[sub->Operand1Id]); Value op2 = Dereference(env.Values[sub->Operand2Id]); env.Values[sub->ResultId] = DoOp(sub->ResultTypeId, Sub<float>, op1, op2); break; } case Op::OpISub: { auto sub = (SISub*)op.Memory; Value op1 = Dereference(env.Values[sub->Operand1Id]); Value op2 = Dereference(env.Values[sub->Operand2Id]); env.Values[sub->ResultId] = DoOp(sub->ResultTypeId, Sub<int>, op1, op2); break; } case Op::OpFDiv: { auto div = (SFDiv*)op.Memory; Value op1 = Dereference(env.Values[div->Operand1Id]); Value op2 = Dereference(env.Values[div->Operand2Id]); env.Values[div->ResultId] = DoOp(div->ResultTypeId, Div<float>, op1, op2); break; } case Op::OpFMul: { auto mul = (SFMul*)op.Memory; Value op1 = Dereference(env.Values[mul->Operand1Id]); Value op2 = Dereference(env.Values[mul->Operand2Id]); env.Values[mul->ResultId] = DoOp(mul->ResultTypeId, Mul<float>, op1, op2); break; } case Op::OpIMul: { auto mul = (SFMul*)op.Memory; Value op1 = Dereference(env.Values[mul->Operand1Id]); Value op2 = Dereference(env.Values[mul->Operand2Id]); env.Values[mul->ResultId] = DoOp(mul->ResultTypeId, Mul<int>, op1, op2); break; } case Op::OpVectorTimesScalar: { auto vts = (SVectorTimesScalar*)op.Memory; Value scalar = Dereference(env.Values[vts->ScalarId]); Value vector = Dereference(env.Values[vts->VectorId]); env.Values[vts->ResultId] = DoOp(vts->ResultTypeId, [scalar](Value comp) {return Mul<float>(scalar, comp);}, vector); break; } case Op::OpSLessThan: { auto lessThan = (SSLessThan*)op.Memory; Value op1 = Dereference(env.Values[lessThan->Operand1Id]); Value op2 = Dereference(env.Values[lessThan->Operand2Id]); env.Values[lessThan->ResultId] = DoOp(lessThan->ResultTypeId, [](Value a, Value b) { return Cmp<int32>(a, b) == -1; }, op1, op2); break; } case Op::OpSGreaterThan: { auto greaterThan = (SSLessThan*)op.Memory; Value op1 = Dereference(env.Values[greaterThan->Operand1Id]); Value op2 = Dereference(env.Values[greaterThan->Operand2Id]); env.Values[greaterThan->ResultId] = DoOp(greaterThan->ResultTypeId, [](Value a, Value b) { return Cmp<int32>(a, b) == 1; }, op1, op2); break; } case Op::OpLoad: { auto load = (SLoad*)op.Memory; auto valueToLoad = env.Values.at(load->PointerId); env.Values[load->ResultId] = valueToLoad; break; } case Op::OpStore: { auto store = (SStore*)op.Memory; auto val = env.Values[store->ObjectId]; auto var = GetType(val.TypeId); if (var.Op == Op::OpTypePointer) { SetVariable(store->PointerId, val.Memory); } else { SetVariable(store->PointerId, &val.Memory); } break; } case Op::OpTextureSample: { auto sample = (STextureSample*)op.Memory; auto sampler = Dereference(env.Values.at(sample->SamplerId)); auto coord = Dereference(env.Values.at(sample->CoordinateId)); Value bias = { 0, 0 }; if (sample->BiasId != 0) { bias = Dereference(env.Values.at(sample->BiasId)); } env.Values[sample->ResultId] = TextureSample(sampler, coord, bias, sample->ResultTypeId); break; } case Op::OpLabel: case Op::OpSelectionMerge: case Op::OpLoopMerge: break; case Op::OpAccessChain: { auto access = (SAccessChain*)op.Memory; auto val = Dereference(env.Values.at(access->BaseId)); uint32* indices = new uint32[access->IndexesIdsCount]; for (int i = 0; i < access->IndexesIdsCount; i++) { indices[i] = *(uint32*)Dereference(env.Values[access->IndexesIds[i]]).Memory; } byte* mem = GetPointerInComposite(val.TypeId, val.Memory, access->IndexesIdsCount, indices); delete indices; Value res = VmInit(access->ResultTypeId, &mem); env.Values[access->ResultId] = res; break; } case Op::OpVectorShuffle: { auto vecShuffle = (SVectorShuffle*)op.Memory; auto vec1 = Dereference(env.Values.at(vecShuffle->Vector1Id)); auto vec2 = Dereference(env.Values.at(vecShuffle->Vector2Id)); auto result = VmInit(vecShuffle->ResultTypeId, nullptr); int v1ElCount = ElementCount(vec1.TypeId); for (int i = 0; i < vecShuffle->ComponentsCount; i++) { int index = vecShuffle->Components[i]; Value toCopy; if (index < v1ElCount) { toCopy = vec1; } else { index -= v1ElCount; toCopy = vec2; } Value elToCopy = IndexMemberValue(toCopy, index); memcpy(IndexMemberValue(result, i).Memory, elToCopy.Memory, GetTypeByteSize(elToCopy.TypeId)); } env.Values[vecShuffle->ResultId] = result; break; } //TODO: FIX INDICES (NOT HIERARCHY!) case Op::OpCompositeExtract: { auto extract = (SCompositeExtract*)op.Memory; auto composite = env.Values[extract->CompositeId]; byte* mem = GetPointerInComposite(composite.TypeId, composite.Memory, extract->IndexesCount, extract->Indexes); Value val = { extract->ResultTypeId, VmAlloc(extract->ResultTypeId) }; memcpy(val.Memory, mem, GetTypeByteSize(val.TypeId)); env.Values[extract->ResultId] = val; break; } case Op::OpCompositeInsert: { auto insert = (SCompositeInsert*)op.Memory; auto composite = Dereference(env.Values[insert->CompositeId]); Value val = Dereference(env.Values.at(insert->ObjectId)); byte* mem = GetPointerInComposite(composite.TypeId, composite.Memory, insert->IndexesCount, insert->Indexes); memcpy(mem, val.Memory, GetTypeByteSize(val.TypeId)); env.Values[insert->ResultId] = VmInit(composite.TypeId, composite.Memory); break; } case Op::OpCompositeConstruct: { auto construct = (SCompositeConstruct*)op.Memory; Value val = { construct->ResultTypeId, VmAlloc(construct->ResultTypeId) }; env.Values[construct->ResultId] = val; byte* memPtr = val.Memory; for (int i = 0; i < construct->ConstituentsIdsCount; i++) { auto memVal = env.Values[construct->ConstituentsIds[i]]; uint32 memSize = GetTypeByteSize(memVal.TypeId); memcpy(memPtr, memVal.Memory, memSize); memPtr += memSize; } assert(memPtr - val.Memory == GetTypeByteSize(construct->ResultTypeId)); break; } case Op::OpVariable: { auto var = (SVariable*)op.Memory; Value val = { var->ResultTypeId, VmAlloc(var->ResultTypeId) }; if (var->InitializerId) { memcpy(val.Memory, env.Values[var->InitializerId].Memory, GetTypeByteSize(val.TypeId)); } else { memset(val.Memory, 0, GetTypeByteSize(val.TypeId)); } env.Values[var->ResultId] = val; break; } case Op::OpReturnValue: { auto ret = (SReturnValue*)op.Memory; return ret->ValueId; } case Op::OpReturn: return 0; default: std::cout << "Unimplemented operation: " << writeOp(op); return -1; } pc++; } return 0; }