int main(int argc, char **argv) { args::ArgumentParser parser("Generates masks in stages.\n" "Stage 1 - Otsu thresholding to generate binary mask\n" "Stage 2 - RATs (optional)\n" "Stage 3 - Hole filling (optional)\n" "http://github.com/spinicist/QUIT"); args::Positional<std::string> input_path(parser, "INPUT_FILE", "Input file"); args::HelpFlag help(parser, "HELP", "Show this help menu", {'h', "help"}); args::Flag verbose(parser, "VERBOSE", "Print more information", {'v', "verbose"}); args::ValueFlag<std::string> outarg( parser, "OUTPUT FILE", "Set output filename, default is input + _mask", {'o', "out"}); args::ValueFlag<int> volume( parser, "VOLUME", "Choose volume to mask in multi-volume file. Default 1, -1 selects last volume", {'v', "volume"}, 0); args::Flag is_complex(parser, "COMPLEX", "Input data is complex, take magnitude first", {'x', "complex"}); args::ValueFlag<float> lower_threshold( parser, "LOWER THRESHOLD", "Specify lower intensity threshold for 1st stage, otherwise Otsu's method is used", {'l', "lower"}, 0.); args::ValueFlag<float> upper_threshold( parser, "UPPER THRESHOLD", "Specify upper intensity threshold for 1st stage, otherwise Otsu's method is used", {'u', "upper"}, std::numeric_limits<float>::infinity()); args::ValueFlag<float> rats( parser, "RATS", "Perform the RATS step, argument is size threshold for connected component", {'r', "rats"}, 0.); args::ValueFlag<int> fillh_radius( parser, "FILL HOLES", "Fill holes in thresholded mask with radius N", {'F', "fillh"}, 0); QI::ParseArgs(parser, argc, argv, verbose); QI::SeriesF::Pointer vols = ITK_NULLPTR; if (is_complex) { vols = QI::ReadMagnitudeImage<QI::SeriesF>(QI::CheckPos(input_path), verbose); } else { vols = QI::ReadImage<QI::SeriesF>(QI::CheckPos(input_path), verbose); } std::string out_path; if (outarg.Get() == "") { out_path = QI::StripExt(input_path.Get()) + "_mask" + QI::OutExt(); } else { out_path = outarg.Get(); } // Extract one volume to process auto region = vols->GetLargestPossibleRegion(); if (static_cast<size_t>(std::abs(volume.Get())) < region.GetSize()[3]) { int volume_to_get = (region.GetSize()[3] + volume.Get()) % region.GetSize()[3]; QI::Log(verbose, "Masking volume {}...", volume_to_get); region.GetModifiableIndex()[3] = volume_to_get; } else { QI::Fail("Specified mask volume was invalid {} ", volume.Get()); } region.GetModifiableSize()[3] = 0; auto vol = itk::ExtractImageFilter<QI::SeriesF, QI::VolumeF>::New(); vol->SetExtractionRegion(region); vol->SetInput(vols); vol->SetDirectionCollapseToSubmatrix(); vol->Update(); QI::VolumeF::Pointer intensity_image = vol->GetOutput(); intensity_image->DisconnectPipeline(); /* * Stage 1 - Otsu or Threshold */ QI::VolumeI::Pointer mask_image = ITK_NULLPTR; if (lower_threshold || upper_threshold) { QI::Log(verbose, "Thresholding range: {}-{}", lower_threshold.Get(), upper_threshold.Get()); mask_image = QI::ThresholdMask(intensity_image, lower_threshold.Get(), upper_threshold.Get()); } else { QI::Log(verbose, "Generating Otsu mask"); mask_image = QI::OtsuMask(intensity_image); } /* * Stage 2 - RATS */ if (rats) { typedef itk::BinaryBallStructuringElement<int, 3> TBall; typedef itk::BinaryErodeImageFilter<QI::VolumeI, QI::VolumeI, TBall> TErode; typedef itk::BinaryDilateImageFilter<QI::VolumeI, QI::VolumeI, TBall> TDilate; float mask_volume = std::numeric_limits<float>::infinity(); float voxel_volume = QI::VoxelVolume(mask_image); QI::Log(verbose, "Voxel volume: {}", voxel_volume); int radius = 0; QI::VolumeI::Pointer mask_rats; while (mask_volume > rats.Get()) { radius++; TBall ball; TBall::SizeType radii; radii.Fill(radius); ball.SetRadius(radii); ball.CreateStructuringElement(); TErode::Pointer erode = TErode::New(); erode->SetInput(mask_image); erode->SetForegroundValue(1); erode->SetBackgroundValue(0); erode->SetKernel(ball); erode->Update(); std::vector<float> kept_sizes = QI::FindLabels(erode->GetOutput(), 0, 1, mask_rats); mask_volume = kept_sizes[0] * voxel_volume; auto dilate = TDilate::New(); dilate->SetKernel(ball); dilate->SetInput(mask_rats); dilate->SetForegroundValue(1); dilate->SetBackgroundValue(0); dilate->Update(); mask_rats = dilate->GetOutput(); mask_rats->DisconnectPipeline(); QI::Log(verbose, "Ran RATS iteration, radius = {} volume = {}", radius, mask_volume); } mask_image = mask_rats; } /* * Stage 3 - Hole Filling */ QI::VolumeI::Pointer finalMask = ITK_NULLPTR; if (fillh_radius) { QI::Log(verbose, "Filling holes"); auto fillHoles = itk::VotingBinaryIterativeHoleFillingImageFilter<QI::VolumeI>::New(); itk::VotingBinaryIterativeHoleFillingImageFilter<QI::VolumeI>::InputSizeType radius; radius.Fill(fillh_radius.Get()); fillHoles->SetInput(mask_image); fillHoles->SetRadius(radius); fillHoles->SetMajorityThreshold(2); // Corresponds to (rad^3-1)/2 + 2 threshold fillHoles->SetBackgroundValue(0); fillHoles->SetForegroundValue(1); fillHoles->SetMaximumNumberOfIterations(3); fillHoles->Update(); mask_image = fillHoles->GetOutput(); mask_image->DisconnectPipeline(); } QI::WriteImage(mask_image, out_path, verbose); QI::Log(verbose, "Finished."); return EXIT_SUCCESS; }
CPieceProjectile::CPieceProjectile(const float3& pos,const float3& speed, LocalS3DO * piece, int flags,CUnit* owner,float radius) : CProjectile(pos,speed,owner, true), flags(flags), dispList(piece?piece->displist:0), drawTrail(true), oldSmoke(pos), curCallback(0), spinPos(0), age(0) { checkCol=false; if(owner){ /* If we're an S3O unit, this is where ProjectileHandler fetches our texture from. */ s3domodel=owner->model; /* If we're part of an S3O unit, save this so we can draw with the right teamcolour. */ colorTeam=owner->team; } /* Don't store piece; owner may be a dying unit, so piece could be freed. */ /* //if (piece->texturetype == 0) { Great. LocalPiece doesn't carry the texture name. HACK TODO PieceProjectile shouldn't need to know about different model formats; push it into Rendering/UnitModels. If this needs to change, also modify Sim/Units/COB/CobInstance.cpp::Explosion. Nothing else wants to draw just one part without PieceInfo, so this polymorphism can stay put for the moment. */ if (piece) { if (piece->original3do != NULL){ piece3do = piece->original3do; pieces3o = NULL; } else if (piece->originals3o != NULL){ piece3do = NULL; pieces3o = piece->originals3o; } } else { piece3do = NULL; pieces3o = NULL; } castShadow=true; if(pos.y-ground->GetApproximateHeight(pos.x,pos.z)>10) useAirLos=true; ENTER_MIXED; numCallback=SAFE_NEW int; *numCallback=0; oldSmokeDir=speed; oldSmokeDir.Normalize(); float3 camDir=(pos-camera->pos).Normalize(); if(camera->pos.distance(pos)+(1-fabs(camDir.dot(oldSmokeDir)))*3000 < 200) drawTrail=false; spinVec=gu->usRandVector(); spinVec.Normalize(); spinSpeed=gu->usRandFloat()*20; //logOutput.Print("New pp with %d", dispList); for(int a=0;a<8;++a){ oldInfos[a]=SAFE_NEW OldInfo; oldInfos[a]->pos=pos; oldInfos[a]->size=gu->usRandFloat()*2+2; } ENTER_SYNCED; SetRadius(radius); drawRadius=32; #ifdef TRACE_SYNC tracefile << "New pieceexplosive: "; tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n"; #endif }
void CFeature::Initialize(const float3& _pos, const FeatureDef* _def, short int _heading, int facing, int _team, int _allyteam, std::string fromUnit, const float3& speed, int _smokeTime) { pos = _pos; def = _def; defName = def->myName; heading = _heading; buildFacing = facing; team = _team; allyteam = _allyteam; emitSmokeTime = _smokeTime; createdFromUnit = fromUnit; ChangeTeam(team); // maybe should not be here, but it prevents crashes caused by team = -1 pos.CheckInBounds(); health = def->maxHealth; blocking = def->blocking; xsize = ((facing & 1) == 0) ? def->xsize : def->zsize; zsize = ((facing & 1) == 1) ? def->xsize : def->zsize; mass = def->mass; noSelect = def->noSelect; if (def->drawType == DRAWTYPE_MODEL) { model = LoadModel(def); if (!model) { logOutput.Print("Features: Couldn't load model for " + defName); SetRadius(0.0f); midPos = pos; } else { height = model->height; SetRadius(model->radius); midPos = pos + model->relMidPos; collisionVolume = new CollisionVolume(def->collisionVolume, model->radius); } } else if (def->drawType >= DRAWTYPE_TREE) { SetRadius(TREE_RADIUS); midPos = pos + (UpVector * TREE_RADIUS); height = 2 * TREE_RADIUS; // LoadFeaturesFromMap() doesn't set a scale for trees collisionVolume = new CollisionVolume(def->collisionVolume, TREE_RADIUS); } else { // geothermal (no collision volume) SetRadius(0.0f); midPos = pos; } featureHandler->AddFeature(this); qf->AddFeature(this); CalculateTransform(); if (blocking) { Block(); } if (def->floating) { finalHeight = ground->GetHeight(pos.x, pos.z); } else { finalHeight = ground->GetHeight2(pos.x, pos.z); } if (def->drawType >= DRAWTYPE_TREE) { treeDrawer->AddTree(def->drawType - 1, pos, 1); } if (speed != ZeroVector) { deathSpeed = speed; } }
/** * Set length property * * @param new_length Length (m) of line */ void SetLength(const fixed new_length) { SetRadius(half(new_length)); }
Monster::Monster() { SetName("Unnamed monster"); SetRadius(0.3); SetType(MONSTER); }
CPieceProjectile::CPieceProjectile(const float3& pos, const float3& speed, LocalModelPiece* piece, int f, CUnit* owner, float radius GML_PARG_C): CProjectile(pos, speed, owner, true, false, true GML_PARG_P), flags(f), dispList(piece? piece->displist: 0), omp(NULL), spinAngle(0.0f), alphaThreshold(0.1f), oldSmoke(pos), drawTrail(true), curCallback(0), age(0) { checkCol = false; if (owner) { // choose a (synced) random tag-postfix string k from the // range given in UnitDef and stick it onto pieceTrailCEGTag // (assumes all possible "tag + k" CEG identifiers are valid) // if this piece does not override the FBI and wants a trail if ((flags & PF_NoCEGTrail) == 0) { const int size = owner->unitDef->pieceTrailCEGTag.size(); const int range = owner->unitDef->pieceTrailCEGRange; const int num = gs->randInt() % range; const char* tag = owner->unitDef->pieceTrailCEGTag.c_str(); if (size > 0) { char cegTag[1024]; SNPRINTF(cegTag, sizeof(cegTag) - 1, "%s%d", tag, num); cegTag[1023] = 0; ceg.Load(explGenHandler, cegTag); } else { flags |= PF_NoCEGTrail; } } /* If we're an S3O unit, this is where ProjectileHandler fetches our texture from. */ s3domodel = owner->model; /* If we're part of an S3O unit, save this so we can draw with the right teamcolour. */ colorTeam = owner->team; // copy the owner's alphaThreshold value alphaThreshold = owner->alphaThreshold; } /* Don't store piece; owner may be a dying unit, so piece could be freed. */ /* //if (piece->texturetype == 0) { Great. LocalPiece doesn't carry the texture name. HACK TODO PieceProjectile shouldn't need to know about different model formats; push it into Rendering/UnitModels. If this needs to change, also modify Sim/Units/COB/CobInstance.cpp::Explosion. Nothing else wants to draw just one part without PieceInfo, so this polymorphism can stay put for the moment. */ if (piece) { if (piece->type == MODELTYPE_3DO) { piece3do = (S3DOPiece*) piece->original; pieces3o = NULL; } else if (piece->type == MODELTYPE_S3O) { piece3do = NULL; pieces3o = (SS3OPiece*) piece->original; } omp = piece->original; } else { piece3do = NULL; pieces3o = NULL; } castShadow = true; if (pos.y - ground->GetApproximateHeight(pos.x, pos.z) > 10) { useAirLos = true; } numCallback = new int; *numCallback = 0; oldSmokeDir = speed; oldSmokeDir.Normalize(); float3 camDir = (pos-camera->pos).Normalize(); if (camera->pos.distance(pos) + (1 - fabs(camDir.dot(oldSmokeDir))) * 3000 < 200) { drawTrail = false; } //! neither spinVec nor spinSpeed technically //! needs to be synced, but since instances of //! this class are themselves synced and have //! LuaSynced{Ctrl, Read} exposure we treat //! them that way for consistency spinVec = gs->randVector(); spinVec.Normalize(); spinSpeed = gs->randFloat() * 20; for (int a = 0; a < 8; ++a) { oldInfos[a] = new OldInfo; oldInfos[a]->pos = pos; oldInfos[a]->size = gu->usRandFloat() * 2 + 2; } SetRadius(radius); drawRadius = 32; #ifdef TRACE_SYNC tracefile << "New CPieceProjectile: "; tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n"; #endif ph->AddProjectile(this); }
CMissileProjectile::CMissileProjectile( const float3& pos, const float3& speed, CUnit* owner, float areaOfEffect, float maxSpeed, int ttl, CUnit* target, const WeaponDef* weaponDef, float3 targetPos) : CWeaponProjectile(pos, speed, owner, target, targetPos, weaponDef, NULL, ttl) , maxSpeed(maxSpeed) , areaOfEffect(areaOfEffect) , age(0) , oldSmoke(pos) , target(target) , decoyTarget(NULL) , drawTrail(true) , numParts(0) , targPos(targetPos) , isWobbling(weaponDef? (weaponDef->wobble > 0): false) , wobbleDir(ZeroVector) , wobbleTime(1) , wobbleDif(ZeroVector) , isDancing(weaponDef? (weaponDef->dance > 0): false) , danceTime(1) , danceMove(ZeroVector) , danceCenter(ZeroVector) , extraHeightTime(0) { projectileType = WEAPON_MISSILE_PROJECTILE; curSpeed = speed.Length(); dir = speed / curSpeed; oldDir = dir; if (target) { AddDeathDependence(target); } SetRadius(0.0f); if (weaponDef) { model = LoadModel(weaponDef); if (model) { SetRadius(model->radius); } } drawRadius = radius + maxSpeed * 8; float3 camDir = (pos - camera->pos).Normalize(); if ((camera->pos.distance(pos) * 0.2f + (1 - fabs(camDir.dot(dir))) * 3000) < 200) { drawTrail = false; } castShadow = true; #ifdef TRACE_SYNC tracefile << "New missile: "; tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n"; #endif if (target) { target->IncomingMissile(this); } if ((weaponDef) && (weaponDef->trajectoryHeight > 0)) { float dist = pos.distance(targPos); extraHeight = (dist * weaponDef->trajectoryHeight); if (dist < maxSpeed) { dist = maxSpeed; } extraHeightTime = (int)(dist / maxSpeed); extraHeightDecay = extraHeight / extraHeightTime; } cegID = gCEG->Load(explGenHandler, cegTag); }
/* ================ idLight::Event_SetRadius ================ */ void idLight::Event_SetRadius( float radius ) { SetRadius( radius ); }
void CFeature::Initialize(const float3& _pos, const FeatureDef* _def, short int _heading, int facing, int _team, std::string fromUnit, const float3& speed) { pos = _pos; def = _def; defName = def->myName; heading = _heading; buildFacing = facing; team = _team; createdFromUnit = fromUnit; ChangeTeam(team); pos.CheckInBounds(); health = def->maxHealth; blocking = def->blocking; xsize = def->xsize; ysize = def->ysize; mass = def->mass; noSelect = def->noSelect; if (def->drawType == DRAWTYPE_3DO) { model = def->LoadModel(team); height = model->height; SetRadius(model->radius); midPos = pos + model->relMidPos; // copy the FeatureDef volume archetype data collisionVolume = SAFE_NEW CollisionVolume(def->collisionVolume); // CFeatureHandler left this volume's axis-scales uninitialized // (ie. no "collisionVolumeScales" tag was defined in FeatureDef) if (collisionVolume->GetScale(COLVOL_AXIS_X) <= 1.0f && collisionVolume->GetScale(COLVOL_AXIS_Y) <= 1.0f && collisionVolume->GetScale(COLVOL_AXIS_Z) <= 1.0f) { collisionVolume->SetDefaultScale(model->radius); } } else if (def->drawType == DRAWTYPE_TREE) { SetRadius(TREE_RADIUS); midPos = pos + (UpVector * TREE_RADIUS); height = 2 * TREE_RADIUS; // copy the FeatureDef volume archetype data collisionVolume = SAFE_NEW CollisionVolume(def->collisionVolume); collisionVolume->SetDefaultScale(TREE_RADIUS); } else { // geothermal (no collision volume) SetRadius(0.0f); midPos = pos; } featureHandler->AddFeature(this); qf->AddFeature(this); CalculateTransform(); if (blocking) { Block(); } if (def->floating) { finalHeight = ground->GetHeight(pos.x, pos.z); } else { finalHeight = ground->GetHeight2(pos.x, pos.z); } if (def->drawType == DRAWTYPE_TREE) { treeDrawer->AddTree(def->modelType, pos, 1); } if (speed != ZeroVector) { deathSpeed = speed; } }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CNPC_Blob::InputSetRadius( inputdata_t &inputdata ) { float flNewRadius = inputdata.value.Float(); SetRadius( flNewRadius ); }
CPieceProjectile::CPieceProjectile(const float3& pos, const float3& speed, LocalModelPiece* lmp, int f, CUnit* owner, float radius): CProjectile(pos, speed, owner, true, false, true), flags(f), dispList(lmp? lmp->dispListID: 0), omp(NULL), spinAngle(0.0f), alphaThreshold(0.1f), oldSmoke(pos), drawTrail(true), curCallback(0), age(0) { checkCol = false; if (owner) { if ((flags & PF_NoCEGTrail) == 0) { const std::vector<std::string>& pieceCEGs = owner->unitDef->pieceCEGTags; const std::string& cegTag = !pieceCEGs.empty()? pieceCEGs[gs->randInt() % pieceCEGs.size()]: ""; if (!cegTag.empty()) { cegID = gCEG->Load(explGenHandler, cegTag.c_str()); } else { flags |= PF_NoCEGTrail; } } /* If we're an S3O unit, this is where ProjectileHandler fetches our texture from. */ model = owner->model; /* If we're part of an S3O unit, save this so we can draw with the right teamcolour. */ colorTeam = owner->team; // copy the owner's alphaThreshold value alphaThreshold = owner->alphaThreshold; } if (lmp) { omp = lmp->original; } else { omp = NULL; } castShadow = true; if (pos.y - ground->GetApproximateHeight(pos.x, pos.z) > 10) { useAirLos = true; } numCallback = new int; *numCallback = 0; oldSmokeDir = speed; oldSmokeDir.Normalize(); float3 camDir = (pos-camera->pos).Normalize(); if (camera->pos.distance(pos) + (1 - fabs(camDir.dot(oldSmokeDir))) * 3000 < 200) { drawTrail = false; } //! neither spinVec nor spinSpeed technically //! needs to be synced, but since instances of //! this class are themselves synced and have //! LuaSynced{Ctrl, Read} exposure we treat //! them that way for consistency spinVec = gs->randVector(); spinVec.Normalize(); spinSpeed = gs->randFloat() * 20; for (int a = 0; a < 8; ++a) { oldInfos[a] = new OldInfo; oldInfos[a]->pos = pos; oldInfos[a]->size = gu->usRandFloat() * 2 + 2; } SetRadius(radius); drawRadius = 32; #ifdef TRACE_SYNC tracefile << "New CPieceProjectile: "; tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n"; #endif ph->AddProjectile(this); }
CFireBallProjectile::CFireBallProjectile(const float3& pos,const float3& speed, CUnit* owner, CUnit *target, const float3 &targetPos, WeaponDef *weaponDef) : CWeaponProjectile(pos,speed, owner, target, targetPos, weaponDef,damages,0) { SetRadius(10.0f); drawRadius=15; }
bool Location::SetRadius(iDataConnection* db, float radius) { SetRadius(radius); return CreateUpdate(db); }
void CStar::Spawn() { // 695500km, the radius of the sun SetRadius(CScalableFloat(695.5f, SCALE_MEGAMETER)); }
void ApplyLinearity(f64 linearity) { f64 radius = Linearity(r, linearity); SetRadius(radius); }